diff --git a/lock.json b/lock.json
index 17457f2c..d36dc03b 100644
--- a/lock.json
+++ b/lock.json
@@ -93,7 +93,6 @@
"packages": [
"api/types/strslice",
"client",
- "pkg/mount",
"pkg/registrar",
"pkg/stringid",
"pkg/stringutils",
@@ -234,8 +233,8 @@
},
{
"name": "github.com/opencontainers/runc",
- "version": "v0.1.1",
- "revision": "baf6536d6259209c3edfa2b22237af82942d3dfa",
+ "branch": "master",
+ "revision": "b263a43430ac6996a4302b891688544225197294",
"packages": [
"libcontainer/apparmor",
"libcontainer/label",
diff --git a/vendor/github.com/opencontainers/runc/.gitignore b/vendor/github.com/opencontainers/runc/.gitignore
index 76c04941..dab07a18 100644
--- a/vendor/github.com/opencontainers/runc/.gitignore
+++ b/vendor/github.com/opencontainers/runc/.gitignore
@@ -1,4 +1,6 @@
vendor/pkg
/runc
+contrib/cmd/recvtty/recvtty
Godeps/_workspace/src/github.com/opencontainers/runc
man/man8
+release
diff --git a/vendor/github.com/opencontainers/runc/.pullapprove.yml b/vendor/github.com/opencontainers/runc/.pullapprove.yml
new file mode 100644
index 00000000..fc8c5d35
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/.pullapprove.yml
@@ -0,0 +1,10 @@
+approve_by_comment: true
+approve_regex: ^LGTM
+reject_regex: ^Rejected
+reset_on_push: true
+author_approval: ignored
+reviewers:
+ teams:
+ - runc-maintainers
+ name: default
+ required: 2
diff --git a/vendor/github.com/opencontainers/runc/.travis.yml b/vendor/github.com/opencontainers/runc/.travis.yml
new file mode 100644
index 00000000..5daaa184
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/.travis.yml
@@ -0,0 +1,26 @@
+language: go
+go:
+ - 1.6.x
+ - 1.7.x
+# - master
+
+# `make ci` uses Docker.
+sudo: required
+services:
+ - docker
+
+env:
+ global:
+ - BUILDTAGS="seccomp apparmor selinux ambient"
+
+before_install:
+ - sudo apt-get -qq update
+ - sudo apt-get install -y libseccomp-dev libapparmor-dev
+ - go get -u github.com/golang/lint/golint
+ - go get -u github.com/vbatts/git-validation
+ - go get -u github.com/mvdan/sh/cmd/shfmt
+
+script:
+ - git-validation -run DCO,short-subject -v -range ${TRAVIS_COMMIT_RANGE}
+ - make BUILDTAGS="${BUILDTAGS}"
+ - make BUILDTAGS="${BUILDTAGS}" clean validate test
diff --git a/vendor/github.com/opencontainers/runc/CONTRIBUTING.md b/vendor/github.com/opencontainers/runc/CONTRIBUTING.md
index 6f341f60..3b674cfc 100644
--- a/vendor/github.com/opencontainers/runc/CONTRIBUTING.md
+++ b/vendor/github.com/opencontainers/runc/CONTRIBUTING.md
@@ -1,5 +1,12 @@
## Contribution Guidelines
+### Security issues
+
+If you are reporting a security issue, do not create an issue or file a pull
+request on GitHub. Instead, disclose the issue responsibly by sending an email
+to security@opencontainers.org (which is inhabited only by the maintainers of
+the various OCI projects).
+
### Pull requests are always welcome
We are always thrilled to receive pull requests, and do our best to
diff --git a/vendor/github.com/opencontainers/runc/Dockerfile b/vendor/github.com/opencontainers/runc/Dockerfile
index a25c2210..6c1d43b0 100644
--- a/vendor/github.com/opencontainers/runc/Dockerfile
+++ b/vendor/github.com/opencontainers/runc/Dockerfile
@@ -1,3 +1,60 @@
-FROM runc_test
+FROM golang:1.7.4
+
+# libseccomp in jessie is not _quite_ new enough -- need backports version
+RUN echo 'deb http://httpredir.debian.org/debian jessie-backports main' > /etc/apt/sources.list.d/backports.list
+
+RUN apt-get update && apt-get install -y \
+ build-essential \
+ curl \
+ gawk \
+ iptables \
+ jq \
+ pkg-config \
+ libaio-dev \
+ libcap-dev \
+ libprotobuf-dev \
+ libprotobuf-c0-dev \
+ libseccomp2/jessie-backports \
+ libseccomp-dev/jessie-backports \
+ protobuf-c-compiler \
+ protobuf-compiler \
+ python-minimal \
+ --no-install-recommends \
+ && apt-get clean
+
+# install bats
+RUN cd /tmp \
+ && git clone https://github.com/sstephenson/bats.git \
+ && cd bats \
+ && git reset --hard 03608115df2071fff4eaaff1605768c275e5f81f \
+ && ./install.sh /usr/local \
+ && rm -rf /tmp/bats
+
+# install criu
+ENV CRIU_VERSION 1.7
+RUN mkdir -p /usr/src/criu \
+ && curl -sSL https://github.com/xemul/criu/archive/v${CRIU_VERSION}.tar.gz | tar -v -C /usr/src/criu/ -xz --strip-components=1 \
+ && cd /usr/src/criu \
+ && make install-criu \
+ && rm -rf /usr/src/criu
+
+# install shfmt
+RUN mkdir -p /go/src/github.com/mvdan \
+ && cd /go/src/github.com/mvdan \
+ && git clone https://github.com/mvdan/sh \
+ && cd sh \
+ && git checkout -f v0.4.0 \
+ && go install ./cmd/shfmt \
+ && rm -rf /go/src/github.com/mvdan
+
+# setup a playground for us to spawn containers in
+ENV ROOTFS /busybox
+RUN mkdir -p ${ROOTFS} \
+ && curl -o- -sSL 'https://github.com/docker-library/busybox/raw/a0558a9006ce0dd6f6ec5d56cfd3f32ebeeb815f/glibc/busybox.tar.xz' | tar xfJC - ${ROOTFS}
+
+
+COPY script/tmpmount /
+WORKDIR /go/src/github.com/opencontainers/runc
+ENTRYPOINT ["/tmpmount"]
+
ADD . /go/src/github.com/opencontainers/runc
-RUN make
diff --git a/vendor/github.com/opencontainers/runc/Godeps/Godeps.json b/vendor/github.com/opencontainers/runc/Godeps/Godeps.json
deleted file mode 100644
index 964fd2a8..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/Godeps.json
+++ /dev/null
@@ -1,77 +0,0 @@
-{
- "ImportPath": "github.com/opencontainers/runc",
- "GoVersion": "go1.5.3",
- "Deps": [
- {
- "ImportPath": "github.com/Sirupsen/logrus",
- "Comment": "v0.7.3-2-g26709e2",
- "Rev": "26709e2714106fb8ad40b773b711ebce25b78914"
- },
- {
- "ImportPath": "github.com/codegangsta/cli",
- "Comment": "1.2.0-187-gc31a797",
- "Rev": "c31a7975863e7810c92e2e288a9ab074f9a88f29"
- },
- {
- "ImportPath": "github.com/coreos/go-systemd/activation",
- "Comment": "v4",
- "Rev": "b4a58d95188dd092ae20072bac14cece0e67c388"
- },
- {
- "ImportPath": "github.com/coreos/go-systemd/dbus",
- "Comment": "v4",
- "Rev": "b4a58d95188dd092ae20072bac14cece0e67c388"
- },
- {
- "ImportPath": "github.com/coreos/go-systemd/util",
- "Comment": "v4",
- "Rev": "b4a58d95188dd092ae20072bac14cece0e67c388"
- },
- {
- "ImportPath": "github.com/docker/docker/pkg/mount",
- "Comment": "v1.4.1-4831-g0f5c9d3",
- "Rev": "0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d"
- },
- {
- "ImportPath": "github.com/docker/docker/pkg/symlink",
- "Comment": "v1.4.1-4831-g0f5c9d3",
- "Rev": "0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d"
- },
- {
- "ImportPath": "github.com/docker/docker/pkg/term",
- "Comment": "v1.4.1-4831-g0f5c9d3",
- "Rev": "0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d"
- },
- {
- "ImportPath": "github.com/docker/go-units",
- "Comment": "v0.1.0",
- "Rev": "9b001659dd36225e356b4467c465d732e745f53d"
- },
- {
- "ImportPath": "github.com/godbus/dbus",
- "Comment": "v3",
- "Rev": "c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f"
- },
- {
- "ImportPath": "github.com/golang/protobuf/proto",
- "Rev": "f7137ae6b19afbfd61a94b746fda3b3fe0491874"
- },
- {
- "ImportPath": "github.com/opencontainers/runtime-spec/specs-go",
- "Comment": "v0.5.0-34-g6e08c69",
- "Rev": "6e08c6983ef8c2173f10ca09266907d4e9e71716"
- },
- {
- "ImportPath": "github.com/seccomp/libseccomp-golang",
- "Rev": "1b506fc7c24eec5a3693cdcbed40d9c226cfc6a1"
- },
- {
- "ImportPath": "github.com/syndtr/gocapability/capability",
- "Rev": "2c00daeb6c3b45114c80ac44119e7b8801fdd852"
- },
- {
- "ImportPath": "github.com/vishvananda/netlink",
- "Rev": "1e2e08e8a2dcdacaae3f14ac44c5cfa31361f270"
- }
- ]
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/Readme b/vendor/github.com/opencontainers/runc/Godeps/Readme
deleted file mode 100644
index 4cdaa53d..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/Readme
+++ /dev/null
@@ -1,5 +0,0 @@
-This directory tree is generated automatically by godep.
-
-Please do not edit.
-
-See https://github.com/tools/godep for more information.
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/.gitignore b/vendor/github.com/opencontainers/runc/Godeps/_workspace/.gitignore
deleted file mode 100644
index f037d684..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/pkg
-/bin
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/.gitignore b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/.gitignore
deleted file mode 100644
index 66be63a0..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-logrus
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/.travis.yml b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/.travis.yml
deleted file mode 100644
index 2d8c0866..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/.travis.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-language: go
-go:
- - 1.2
- - 1.3
- - 1.4
- - tip
-install:
- - go get -t ./...
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/CHANGELOG.md b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/CHANGELOG.md
deleted file mode 100644
index eb72bff9..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/CHANGELOG.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# 0.7.3
-
-formatter/\*: allow configuration of timestamp layout
-
-# 0.7.2
-
-formatter/text: Add configuration option for time format (#158)
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/LICENSE b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/LICENSE
deleted file mode 100644
index f090cb42..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2014 Simon Eskildsen
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/README.md b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/README.md
deleted file mode 100644
index d55f9092..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/README.md
+++ /dev/null
@@ -1,349 +0,0 @@
-# Logrus [![Build Status](https://travis-ci.org/Sirupsen/logrus.svg?branch=master)](https://travis-ci.org/Sirupsen/logrus) [![godoc reference](https://godoc.org/github.com/Sirupsen/logrus?status.png)][godoc]
-
-Logrus is a structured logger for Go (golang), completely API compatible with
-the standard library logger. [Godoc][godoc]. **Please note the Logrus API is not
-yet stable (pre 1.0). Logrus itself is completely stable and has been used in
-many large deployments. The core API is unlikely to change much but please
-version control your Logrus to make sure you aren't fetching latest `master` on
-every build.**
-
-Nicely color-coded in development (when a TTY is attached, otherwise just
-plain text):
-
-![Colored](http://i.imgur.com/PY7qMwd.png)
-
-With `log.Formatter = new(logrus.JSONFormatter)`, for easy parsing by logstash
-or Splunk:
-
-```json
-{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the
-ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"}
-
-{"level":"warning","msg":"The group's number increased tremendously!",
-"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"}
-
-{"animal":"walrus","level":"info","msg":"A giant walrus appears!",
-"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"}
-
-{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.",
-"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"}
-
-{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true,
-"time":"2014-03-10 19:57:38.562543128 -0400 EDT"}
-```
-
-With the default `log.Formatter = new(logrus.TextFormatter)` when a TTY is not
-attached, the output is compatible with the
-[logfmt](http://godoc.org/github.com/kr/logfmt) format:
-
-```text
-time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8
-time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
-time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true
-time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4
-time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009
-time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true
-exit status 1
-```
-
-#### Example
-
-The simplest way to use Logrus is simply the package-level exported logger:
-
-```go
-package main
-
-import (
- log "github.com/Sirupsen/logrus"
-)
-
-func main() {
- log.WithFields(log.Fields{
- "animal": "walrus",
- }).Info("A walrus appears")
-}
-```
-
-Note that it's completely api-compatible with the stdlib logger, so you can
-replace your `log` imports everywhere with `log "github.com/Sirupsen/logrus"`
-and you'll now have the flexibility of Logrus. You can customize it all you
-want:
-
-```go
-package main
-
-import (
- "os"
- log "github.com/Sirupsen/logrus"
- "github.com/Sirupsen/logrus/hooks/airbrake"
-)
-
-func init() {
- // Log as JSON instead of the default ASCII formatter.
- log.SetFormatter(&log.JSONFormatter{})
-
- // Use the Airbrake hook to report errors that have Error severity or above to
- // an exception tracker. You can create custom hooks, see the Hooks section.
- log.AddHook(airbrake.NewHook("https://example.com", "xyz", "development"))
-
- // Output to stderr instead of stdout, could also be a file.
- log.SetOutput(os.Stderr)
-
- // Only log the warning severity or above.
- log.SetLevel(log.WarnLevel)
-}
-
-func main() {
- log.WithFields(log.Fields{
- "animal": "walrus",
- "size": 10,
- }).Info("A group of walrus emerges from the ocean")
-
- log.WithFields(log.Fields{
- "omg": true,
- "number": 122,
- }).Warn("The group's number increased tremendously!")
-
- log.WithFields(log.Fields{
- "omg": true,
- "number": 100,
- }).Fatal("The ice breaks!")
-
- // A common pattern is to re-use fields between logging statements by re-using
- // the logrus.Entry returned from WithFields()
- contextLogger := log.WithFields(log.Fields{
- "common": "this is a common field",
- "other": "I also should be logged always",
- })
-
- contextLogger.Info("I'll be logged with common and other field")
- contextLogger.Info("Me too")
-}
-```
-
-For more advanced usage such as logging to multiple locations from the same
-application, you can also create an instance of the `logrus` Logger:
-
-```go
-package main
-
-import (
- "github.com/Sirupsen/logrus"
-)
-
-// Create a new instance of the logger. You can have any number of instances.
-var log = logrus.New()
-
-func main() {
- // The API for setting attributes is a little different than the package level
- // exported logger. See Godoc.
- log.Out = os.Stderr
-
- log.WithFields(logrus.Fields{
- "animal": "walrus",
- "size": 10,
- }).Info("A group of walrus emerges from the ocean")
-}
-```
-
-#### Fields
-
-Logrus encourages careful, structured logging though logging fields instead of
-long, unparseable error messages. For example, instead of: `log.Fatalf("Failed
-to send event %s to topic %s with key %d")`, you should log the much more
-discoverable:
-
-```go
-log.WithFields(log.Fields{
- "event": event,
- "topic": topic,
- "key": key,
-}).Fatal("Failed to send event")
-```
-
-We've found this API forces you to think about logging in a way that produces
-much more useful logging messages. We've been in countless situations where just
-a single added field to a log statement that was already there would've saved us
-hours. The `WithFields` call is optional.
-
-In general, with Logrus using any of the `printf`-family functions should be
-seen as a hint you should add a field, however, you can still use the
-`printf`-family functions with Logrus.
-
-#### Hooks
-
-You can add hooks for logging levels. For example to send errors to an exception
-tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to
-multiple places simultaneously, e.g. syslog.
-
-Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in
-`init`:
-
-```go
-import (
- log "github.com/Sirupsen/logrus"
- "github.com/Sirupsen/logrus/hooks/airbrake"
- "github.com/Sirupsen/logrus/hooks/syslog"
- "log/syslog"
-)
-
-func init() {
- log.AddHook(airbrake.NewHook("https://example.com", "xyz", "development"))
-
- hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
- if err != nil {
- log.Error("Unable to connect to local syslog daemon")
- } else {
- log.AddHook(hook)
- }
-}
-```
-
-
-| Hook | Description |
-| ----- | ----------- |
-| [Airbrake](https://github.com/Sirupsen/logrus/blob/master/hooks/airbrake/airbrake.go) | Send errors to an exception tracking service compatible with the Airbrake API. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. |
-| [Papertrail](https://github.com/Sirupsen/logrus/blob/master/hooks/papertrail/papertrail.go) | Send errors to the Papertrail hosted logging service via UDP. |
-| [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. |
-| [BugSnag](https://github.com/Sirupsen/logrus/blob/master/hooks/bugsnag/bugsnag.go) | Send errors to the Bugsnag exception tracking service. |
-| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. |
-| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) |
-| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. |
-| [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` |
-| [Graylog](https://github.com/gemnasium/logrus-hooks/tree/master/graylog) | Hook for logging to [Graylog](http://graylog2.org/) |
-
-#### Level logging
-
-Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic.
-
-```go
-log.Debug("Useful debugging information.")
-log.Info("Something noteworthy happened!")
-log.Warn("You should probably take a look at this.")
-log.Error("Something failed but I'm not quitting.")
-// Calls os.Exit(1) after logging
-log.Fatal("Bye.")
-// Calls panic() after logging
-log.Panic("I'm bailing.")
-```
-
-You can set the logging level on a `Logger`, then it will only log entries with
-that severity or anything above it:
-
-```go
-// Will log anything that is info or above (warn, error, fatal, panic). Default.
-log.SetLevel(log.InfoLevel)
-```
-
-It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose
-environment if your application has that.
-
-#### Entries
-
-Besides the fields added with `WithField` or `WithFields` some fields are
-automatically added to all logging events:
-
-1. `time`. The timestamp when the entry was created.
-2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after
- the `AddFields` call. E.g. `Failed to send event.`
-3. `level`. The logging level. E.g. `info`.
-
-#### Environments
-
-Logrus has no notion of environment.
-
-If you wish for hooks and formatters to only be used in specific environments,
-you should handle that yourself. For example, if your application has a global
-variable `Environment`, which is a string representation of the environment you
-could do:
-
-```go
-import (
- log "github.com/Sirupsen/logrus"
-)
-
-init() {
- // do something here to set environment depending on an environment variable
- // or command-line flag
- if Environment == "production" {
- log.SetFormatter(logrus.JSONFormatter)
- } else {
- // The TextFormatter is default, you don't actually have to do this.
- log.SetFormatter(logrus.TextFormatter)
- }
-}
-```
-
-This configuration is how `logrus` was intended to be used, but JSON in
-production is mostly only useful if you do log aggregation with tools like
-Splunk or Logstash.
-
-#### Formatters
-
-The built-in logging formatters are:
-
-* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise
- without colors.
- * *Note:* to force colored output when there is no TTY, set the `ForceColors`
- field to `true`. To force no colored output even if there is a TTY set the
- `DisableColors` field to `true`
-* `logrus.JSONFormatter`. Logs fields as JSON.
-* `logrus_logstash.LogstashFormatter`. Logs fields as Logstash Events (http://logstash.net).
-
- ```go
- logrus.SetFormatter(&logrus_logstash.LogstashFormatter{Type: “application_name"})
- ```
-
-Third party logging formatters:
-
-* [`zalgo`](https://github.com/aybabtme/logzalgo): invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
-
-You can define your formatter by implementing the `Formatter` interface,
-requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a
-`Fields` type (`map[string]interface{}`) with all your fields as well as the
-default ones (see Entries section above):
-
-```go
-type MyJSONFormatter struct {
-}
-
-log.SetFormatter(new(MyJSONFormatter))
-
-func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
- // Note this doesn't include Time, Level and Message which are available on
- // the Entry. Consult `godoc` on information about those fields or read the
- // source of the official loggers.
- serialized, err := json.Marshal(entry.Data)
- if err != nil {
- return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
- }
- return append(serialized, '\n'), nil
-}
-```
-
-#### Logger as an `io.Writer`
-
-Logrus can be transormed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it.
-
-```go
-w := logger.Writer()
-defer w.Close()
-
-srv := http.Server{
- // create a stdlib log.Logger that writes to
- // logrus.Logger.
- ErrorLog: log.New(w, "", 0),
-}
-```
-
-Each line written to that writer will be printed the usual way, using formatters
-and hooks. The level for those entries is `info`.
-
-#### Rotation
-
-Log rotation is not provided with Logrus. Log rotation should be done by an
-external program (like `logrotate(8)`) that can compress and delete old log
-entries. It should not be a feature of the application-level logger.
-
-
-[godoc]: https://godoc.org/github.com/Sirupsen/logrus
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/entry.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/entry.go
deleted file mode 100644
index 17fe6f70..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/entry.go
+++ /dev/null
@@ -1,252 +0,0 @@
-package logrus
-
-import (
- "bytes"
- "fmt"
- "io"
- "os"
- "time"
-)
-
-// An entry is the final or intermediate Logrus logging entry. It contains all
-// the fields passed with WithField{,s}. It's finally logged when Debug, Info,
-// Warn, Error, Fatal or Panic is called on it. These objects can be reused and
-// passed around as much as you wish to avoid field duplication.
-type Entry struct {
- Logger *Logger
-
- // Contains all the fields set by the user.
- Data Fields
-
- // Time at which the log entry was created
- Time time.Time
-
- // Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
- Level Level
-
- // Message passed to Debug, Info, Warn, Error, Fatal or Panic
- Message string
-}
-
-func NewEntry(logger *Logger) *Entry {
- return &Entry{
- Logger: logger,
- // Default is three fields, give a little extra room
- Data: make(Fields, 5),
- }
-}
-
-// Returns a reader for the entry, which is a proxy to the formatter.
-func (entry *Entry) Reader() (*bytes.Buffer, error) {
- serialized, err := entry.Logger.Formatter.Format(entry)
- return bytes.NewBuffer(serialized), err
-}
-
-// Returns the string representation from the reader and ultimately the
-// formatter.
-func (entry *Entry) String() (string, error) {
- reader, err := entry.Reader()
- if err != nil {
- return "", err
- }
-
- return reader.String(), err
-}
-
-// Add a single field to the Entry.
-func (entry *Entry) WithField(key string, value interface{}) *Entry {
- return entry.WithFields(Fields{key: value})
-}
-
-// Add a map of fields to the Entry.
-func (entry *Entry) WithFields(fields Fields) *Entry {
- data := Fields{}
- for k, v := range entry.Data {
- data[k] = v
- }
- for k, v := range fields {
- data[k] = v
- }
- return &Entry{Logger: entry.Logger, Data: data}
-}
-
-func (entry *Entry) log(level Level, msg string) {
- entry.Time = time.Now()
- entry.Level = level
- entry.Message = msg
-
- if err := entry.Logger.Hooks.Fire(level, entry); err != nil {
- entry.Logger.mu.Lock()
- fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
- entry.Logger.mu.Unlock()
- }
-
- reader, err := entry.Reader()
- if err != nil {
- entry.Logger.mu.Lock()
- fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
- entry.Logger.mu.Unlock()
- }
-
- entry.Logger.mu.Lock()
- defer entry.Logger.mu.Unlock()
-
- _, err = io.Copy(entry.Logger.Out, reader)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
- }
-
- // To avoid Entry#log() returning a value that only would make sense for
- // panic() to use in Entry#Panic(), we avoid the allocation by checking
- // directly here.
- if level <= PanicLevel {
- panic(entry)
- }
-}
-
-func (entry *Entry) Debug(args ...interface{}) {
- if entry.Logger.Level >= DebugLevel {
- entry.log(DebugLevel, fmt.Sprint(args...))
- }
-}
-
-func (entry *Entry) Print(args ...interface{}) {
- entry.Info(args...)
-}
-
-func (entry *Entry) Info(args ...interface{}) {
- if entry.Logger.Level >= InfoLevel {
- entry.log(InfoLevel, fmt.Sprint(args...))
- }
-}
-
-func (entry *Entry) Warn(args ...interface{}) {
- if entry.Logger.Level >= WarnLevel {
- entry.log(WarnLevel, fmt.Sprint(args...))
- }
-}
-
-func (entry *Entry) Warning(args ...interface{}) {
- entry.Warn(args...)
-}
-
-func (entry *Entry) Error(args ...interface{}) {
- if entry.Logger.Level >= ErrorLevel {
- entry.log(ErrorLevel, fmt.Sprint(args...))
- }
-}
-
-func (entry *Entry) Fatal(args ...interface{}) {
- if entry.Logger.Level >= FatalLevel {
- entry.log(FatalLevel, fmt.Sprint(args...))
- }
- os.Exit(1)
-}
-
-func (entry *Entry) Panic(args ...interface{}) {
- if entry.Logger.Level >= PanicLevel {
- entry.log(PanicLevel, fmt.Sprint(args...))
- }
- panic(fmt.Sprint(args...))
-}
-
-// Entry Printf family functions
-
-func (entry *Entry) Debugf(format string, args ...interface{}) {
- if entry.Logger.Level >= DebugLevel {
- entry.Debug(fmt.Sprintf(format, args...))
- }
-}
-
-func (entry *Entry) Infof(format string, args ...interface{}) {
- if entry.Logger.Level >= InfoLevel {
- entry.Info(fmt.Sprintf(format, args...))
- }
-}
-
-func (entry *Entry) Printf(format string, args ...interface{}) {
- entry.Infof(format, args...)
-}
-
-func (entry *Entry) Warnf(format string, args ...interface{}) {
- if entry.Logger.Level >= WarnLevel {
- entry.Warn(fmt.Sprintf(format, args...))
- }
-}
-
-func (entry *Entry) Warningf(format string, args ...interface{}) {
- entry.Warnf(format, args...)
-}
-
-func (entry *Entry) Errorf(format string, args ...interface{}) {
- if entry.Logger.Level >= ErrorLevel {
- entry.Error(fmt.Sprintf(format, args...))
- }
-}
-
-func (entry *Entry) Fatalf(format string, args ...interface{}) {
- if entry.Logger.Level >= FatalLevel {
- entry.Fatal(fmt.Sprintf(format, args...))
- }
-}
-
-func (entry *Entry) Panicf(format string, args ...interface{}) {
- if entry.Logger.Level >= PanicLevel {
- entry.Panic(fmt.Sprintf(format, args...))
- }
-}
-
-// Entry Println family functions
-
-func (entry *Entry) Debugln(args ...interface{}) {
- if entry.Logger.Level >= DebugLevel {
- entry.Debug(entry.sprintlnn(args...))
- }
-}
-
-func (entry *Entry) Infoln(args ...interface{}) {
- if entry.Logger.Level >= InfoLevel {
- entry.Info(entry.sprintlnn(args...))
- }
-}
-
-func (entry *Entry) Println(args ...interface{}) {
- entry.Infoln(args...)
-}
-
-func (entry *Entry) Warnln(args ...interface{}) {
- if entry.Logger.Level >= WarnLevel {
- entry.Warn(entry.sprintlnn(args...))
- }
-}
-
-func (entry *Entry) Warningln(args ...interface{}) {
- entry.Warnln(args...)
-}
-
-func (entry *Entry) Errorln(args ...interface{}) {
- if entry.Logger.Level >= ErrorLevel {
- entry.Error(entry.sprintlnn(args...))
- }
-}
-
-func (entry *Entry) Fatalln(args ...interface{}) {
- if entry.Logger.Level >= FatalLevel {
- entry.Fatal(entry.sprintlnn(args...))
- }
-}
-
-func (entry *Entry) Panicln(args ...interface{}) {
- if entry.Logger.Level >= PanicLevel {
- entry.Panic(entry.sprintlnn(args...))
- }
-}
-
-// Sprintlnn => Sprint no newline. This is to get the behavior of how
-// fmt.Sprintln where spaces are always added between operands, regardless of
-// their type. Instead of vendoring the Sprintln implementation to spare a
-// string allocation, we do the simplest thing.
-func (entry *Entry) sprintlnn(args ...interface{}) string {
- msg := fmt.Sprintln(args...)
- return msg[:len(msg)-1]
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/basic/basic.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/basic/basic.go
deleted file mode 100644
index a1623ec0..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/basic/basic.go
+++ /dev/null
@@ -1,50 +0,0 @@
-package main
-
-import (
- "github.com/Sirupsen/logrus"
-)
-
-var log = logrus.New()
-
-func init() {
- log.Formatter = new(logrus.JSONFormatter)
- log.Formatter = new(logrus.TextFormatter) // default
- log.Level = logrus.DebugLevel
-}
-
-func main() {
- defer func() {
- err := recover()
- if err != nil {
- log.WithFields(logrus.Fields{
- "omg": true,
- "err": err,
- "number": 100,
- }).Fatal("The ice breaks!")
- }
- }()
-
- log.WithFields(logrus.Fields{
- "animal": "walrus",
- "number": 8,
- }).Debug("Started observing beach")
-
- log.WithFields(logrus.Fields{
- "animal": "walrus",
- "size": 10,
- }).Info("A group of walrus emerges from the ocean")
-
- log.WithFields(logrus.Fields{
- "omg": true,
- "number": 122,
- }).Warn("The group's number increased tremendously!")
-
- log.WithFields(logrus.Fields{
- "temperature": -4,
- }).Debug("Temperature changes")
-
- log.WithFields(logrus.Fields{
- "animal": "orca",
- "size": 9009,
- }).Panic("It's over 9000!")
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/hook/hook.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/hook/hook.go
deleted file mode 100644
index cb5759a3..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/hook/hook.go
+++ /dev/null
@@ -1,30 +0,0 @@
-package main
-
-import (
- "github.com/Sirupsen/logrus"
- "github.com/Sirupsen/logrus/hooks/airbrake"
-)
-
-var log = logrus.New()
-
-func init() {
- log.Formatter = new(logrus.TextFormatter) // default
- log.Hooks.Add(airbrake.NewHook("https://example.com", "xyz", "development"))
-}
-
-func main() {
- log.WithFields(logrus.Fields{
- "animal": "walrus",
- "size": 10,
- }).Info("A group of walrus emerges from the ocean")
-
- log.WithFields(logrus.Fields{
- "omg": true,
- "number": 122,
- }).Warn("The group's number increased tremendously!")
-
- log.WithFields(logrus.Fields{
- "omg": true,
- "number": 100,
- }).Fatal("The ice breaks!")
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/exported.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/exported.go
deleted file mode 100644
index a67e1b80..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/exported.go
+++ /dev/null
@@ -1,188 +0,0 @@
-package logrus
-
-import (
- "io"
-)
-
-var (
- // std is the name of the standard logger in stdlib `log`
- std = New()
-)
-
-func StandardLogger() *Logger {
- return std
-}
-
-// SetOutput sets the standard logger output.
-func SetOutput(out io.Writer) {
- std.mu.Lock()
- defer std.mu.Unlock()
- std.Out = out
-}
-
-// SetFormatter sets the standard logger formatter.
-func SetFormatter(formatter Formatter) {
- std.mu.Lock()
- defer std.mu.Unlock()
- std.Formatter = formatter
-}
-
-// SetLevel sets the standard logger level.
-func SetLevel(level Level) {
- std.mu.Lock()
- defer std.mu.Unlock()
- std.Level = level
-}
-
-// GetLevel returns the standard logger level.
-func GetLevel() Level {
- std.mu.Lock()
- defer std.mu.Unlock()
- return std.Level
-}
-
-// AddHook adds a hook to the standard logger hooks.
-func AddHook(hook Hook) {
- std.mu.Lock()
- defer std.mu.Unlock()
- std.Hooks.Add(hook)
-}
-
-// WithField creates an entry from the standard logger and adds a field to
-// it. If you want multiple fields, use `WithFields`.
-//
-// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
-// or Panic on the Entry it returns.
-func WithField(key string, value interface{}) *Entry {
- return std.WithField(key, value)
-}
-
-// WithFields creates an entry from the standard logger and adds multiple
-// fields to it. This is simply a helper for `WithField`, invoking it
-// once for each field.
-//
-// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
-// or Panic on the Entry it returns.
-func WithFields(fields Fields) *Entry {
- return std.WithFields(fields)
-}
-
-// Debug logs a message at level Debug on the standard logger.
-func Debug(args ...interface{}) {
- std.Debug(args...)
-}
-
-// Print logs a message at level Info on the standard logger.
-func Print(args ...interface{}) {
- std.Print(args...)
-}
-
-// Info logs a message at level Info on the standard logger.
-func Info(args ...interface{}) {
- std.Info(args...)
-}
-
-// Warn logs a message at level Warn on the standard logger.
-func Warn(args ...interface{}) {
- std.Warn(args...)
-}
-
-// Warning logs a message at level Warn on the standard logger.
-func Warning(args ...interface{}) {
- std.Warning(args...)
-}
-
-// Error logs a message at level Error on the standard logger.
-func Error(args ...interface{}) {
- std.Error(args...)
-}
-
-// Panic logs a message at level Panic on the standard logger.
-func Panic(args ...interface{}) {
- std.Panic(args...)
-}
-
-// Fatal logs a message at level Fatal on the standard logger.
-func Fatal(args ...interface{}) {
- std.Fatal(args...)
-}
-
-// Debugf logs a message at level Debug on the standard logger.
-func Debugf(format string, args ...interface{}) {
- std.Debugf(format, args...)
-}
-
-// Printf logs a message at level Info on the standard logger.
-func Printf(format string, args ...interface{}) {
- std.Printf(format, args...)
-}
-
-// Infof logs a message at level Info on the standard logger.
-func Infof(format string, args ...interface{}) {
- std.Infof(format, args...)
-}
-
-// Warnf logs a message at level Warn on the standard logger.
-func Warnf(format string, args ...interface{}) {
- std.Warnf(format, args...)
-}
-
-// Warningf logs a message at level Warn on the standard logger.
-func Warningf(format string, args ...interface{}) {
- std.Warningf(format, args...)
-}
-
-// Errorf logs a message at level Error on the standard logger.
-func Errorf(format string, args ...interface{}) {
- std.Errorf(format, args...)
-}
-
-// Panicf logs a message at level Panic on the standard logger.
-func Panicf(format string, args ...interface{}) {
- std.Panicf(format, args...)
-}
-
-// Fatalf logs a message at level Fatal on the standard logger.
-func Fatalf(format string, args ...interface{}) {
- std.Fatalf(format, args...)
-}
-
-// Debugln logs a message at level Debug on the standard logger.
-func Debugln(args ...interface{}) {
- std.Debugln(args...)
-}
-
-// Println logs a message at level Info on the standard logger.
-func Println(args ...interface{}) {
- std.Println(args...)
-}
-
-// Infoln logs a message at level Info on the standard logger.
-func Infoln(args ...interface{}) {
- std.Infoln(args...)
-}
-
-// Warnln logs a message at level Warn on the standard logger.
-func Warnln(args ...interface{}) {
- std.Warnln(args...)
-}
-
-// Warningln logs a message at level Warn on the standard logger.
-func Warningln(args ...interface{}) {
- std.Warningln(args...)
-}
-
-// Errorln logs a message at level Error on the standard logger.
-func Errorln(args ...interface{}) {
- std.Errorln(args...)
-}
-
-// Panicln logs a message at level Panic on the standard logger.
-func Panicln(args ...interface{}) {
- std.Panicln(args...)
-}
-
-// Fatalln logs a message at level Fatal on the standard logger.
-func Fatalln(args ...interface{}) {
- std.Fatalln(args...)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/formatter.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/formatter.go
deleted file mode 100644
index 104d689f..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/formatter.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package logrus
-
-import "time"
-
-const DefaultTimestampFormat = time.RFC3339
-
-// The Formatter interface is used to implement a custom Formatter. It takes an
-// `Entry`. It exposes all the fields, including the default ones:
-//
-// * `entry.Data["msg"]`. The message passed from Info, Warn, Error ..
-// * `entry.Data["time"]`. The timestamp.
-// * `entry.Data["level"]. The level the entry was logged at.
-//
-// Any additional fields added with `WithField` or `WithFields` are also in
-// `entry.Data`. Format is expected to return an array of bytes which are then
-// logged to `logger.Out`.
-type Formatter interface {
- Format(*Entry) ([]byte, error)
-}
-
-// This is to not silently overwrite `time`, `msg` and `level` fields when
-// dumping it. If this code wasn't there doing:
-//
-// logrus.WithField("level", 1).Info("hello")
-//
-// Would just silently drop the user provided level. Instead with this code
-// it'll logged as:
-//
-// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
-//
-// It's not exported because it's still using Data in an opinionated way. It's to
-// avoid code duplication between the two default formatters.
-func prefixFieldClashes(data Fields) {
- _, ok := data["time"]
- if ok {
- data["fields.time"] = data["time"]
- }
-
- _, ok = data["msg"]
- if ok {
- data["fields.msg"] = data["msg"]
- }
-
- _, ok = data["level"]
- if ok {
- data["fields.level"] = data["level"]
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/formatters/logstash/logstash.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/formatters/logstash/logstash.go
deleted file mode 100644
index 8ea93ddf..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/formatters/logstash/logstash.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package logstash
-
-import (
- "encoding/json"
- "fmt"
-
- "github.com/Sirupsen/logrus"
-)
-
-// Formatter generates json in logstash format.
-// Logstash site: http://logstash.net/
-type LogstashFormatter struct {
- Type string // if not empty use for logstash type field.
-
- // TimestampFormat sets the format used for timestamps.
- TimestampFormat string
-}
-
-func (f *LogstashFormatter) Format(entry *logrus.Entry) ([]byte, error) {
- entry.Data["@version"] = 1
-
- if f.TimestampFormat == "" {
- f.TimestampFormat = logrus.DefaultTimestampFormat
- }
-
- entry.Data["@timestamp"] = entry.Time.Format(f.TimestampFormat)
-
- // set message field
- v, ok := entry.Data["message"]
- if ok {
- entry.Data["fields.message"] = v
- }
- entry.Data["message"] = entry.Message
-
- // set level field
- v, ok = entry.Data["level"]
- if ok {
- entry.Data["fields.level"] = v
- }
- entry.Data["level"] = entry.Level.String()
-
- // set type field
- if f.Type != "" {
- v, ok = entry.Data["type"]
- if ok {
- entry.Data["fields.type"] = v
- }
- entry.Data["type"] = f.Type
- }
-
- serialized, err := json.Marshal(entry.Data)
- if err != nil {
- return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
- }
- return append(serialized, '\n'), nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks.go
deleted file mode 100644
index 0da2b365..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package logrus
-
-// A hook to be fired when logging on the logging levels returned from
-// `Levels()` on your implementation of the interface. Note that this is not
-// fired in a goroutine or a channel with workers, you should handle such
-// functionality yourself if your call is non-blocking and you don't wish for
-// the logging calls for levels returned from `Levels()` to block.
-type Hook interface {
- Levels() []Level
- Fire(*Entry) error
-}
-
-// Internal type for storing the hooks on a logger instance.
-type levelHooks map[Level][]Hook
-
-// Add a hook to an instance of logger. This is called with
-// `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface.
-func (hooks levelHooks) Add(hook Hook) {
- for _, level := range hook.Levels() {
- hooks[level] = append(hooks[level], hook)
- }
-}
-
-// Fire all the hooks for the passed level. Used by `entry.log` to fire
-// appropriate hooks for a log entry.
-func (hooks levelHooks) Fire(level Level, entry *Entry) error {
- for _, hook := range hooks[level] {
- if err := hook.Fire(entry); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go
deleted file mode 100644
index b0502c33..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package airbrake
-
-import (
- "errors"
- "fmt"
-
- "github.com/Sirupsen/logrus"
- "github.com/tobi/airbrake-go"
-)
-
-// AirbrakeHook to send exceptions to an exception-tracking service compatible
-// with the Airbrake API.
-type airbrakeHook struct {
- APIKey string
- Endpoint string
- Environment string
-}
-
-func NewHook(endpoint, apiKey, env string) *airbrakeHook {
- return &airbrakeHook{
- APIKey: apiKey,
- Endpoint: endpoint,
- Environment: env,
- }
-}
-
-func (hook *airbrakeHook) Fire(entry *logrus.Entry) error {
- airbrake.ApiKey = hook.APIKey
- airbrake.Endpoint = hook.Endpoint
- airbrake.Environment = hook.Environment
-
- var notifyErr error
- err, ok := entry.Data["error"].(error)
- if ok {
- notifyErr = err
- } else {
- notifyErr = errors.New(entry.Message)
- }
-
- airErr := airbrake.Notify(notifyErr)
- if airErr != nil {
- return fmt.Errorf("Failed to send error to Airbrake: %s", airErr)
- }
-
- return nil
-}
-
-func (hook *airbrakeHook) Levels() []logrus.Level {
- return []logrus.Level{
- logrus.ErrorLevel,
- logrus.FatalLevel,
- logrus.PanicLevel,
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag.go
deleted file mode 100644
index d20a0f54..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag.go
+++ /dev/null
@@ -1,68 +0,0 @@
-package logrus_bugsnag
-
-import (
- "errors"
-
- "github.com/Sirupsen/logrus"
- "github.com/bugsnag/bugsnag-go"
-)
-
-type bugsnagHook struct{}
-
-// ErrBugsnagUnconfigured is returned if NewBugsnagHook is called before
-// bugsnag.Configure. Bugsnag must be configured before the hook.
-var ErrBugsnagUnconfigured = errors.New("bugsnag must be configured before installing this logrus hook")
-
-// ErrBugsnagSendFailed indicates that the hook failed to submit an error to
-// bugsnag. The error was successfully generated, but `bugsnag.Notify()`
-// failed.
-type ErrBugsnagSendFailed struct {
- err error
-}
-
-func (e ErrBugsnagSendFailed) Error() string {
- return "failed to send error to Bugsnag: " + e.err.Error()
-}
-
-// NewBugsnagHook initializes a logrus hook which sends exceptions to an
-// exception-tracking service compatible with the Bugsnag API. Before using
-// this hook, you must call bugsnag.Configure(). The returned object should be
-// registered with a log via `AddHook()`
-//
-// Entries that trigger an Error, Fatal or Panic should now include an "error"
-// field to send to Bugsnag.
-func NewBugsnagHook() (*bugsnagHook, error) {
- if bugsnag.Config.APIKey == "" {
- return nil, ErrBugsnagUnconfigured
- }
- return &bugsnagHook{}, nil
-}
-
-// Fire forwards an error to Bugsnag. Given a logrus.Entry, it extracts the
-// "error" field (or the Message if the error isn't present) and sends it off.
-func (hook *bugsnagHook) Fire(entry *logrus.Entry) error {
- var notifyErr error
- err, ok := entry.Data["error"].(error)
- if ok {
- notifyErr = err
- } else {
- notifyErr = errors.New(entry.Message)
- }
-
- bugsnagErr := bugsnag.Notify(notifyErr)
- if bugsnagErr != nil {
- return ErrBugsnagSendFailed{bugsnagErr}
- }
-
- return nil
-}
-
-// Levels enumerates the log levels on which the error should be forwarded to
-// bugsnag: everything at or above the "Error" level.
-func (hook *bugsnagHook) Levels() []logrus.Level {
- return []logrus.Level{
- logrus.ErrorLevel,
- logrus.FatalLevel,
- logrus.PanicLevel,
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/README.md b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/README.md
deleted file mode 100644
index ae61e922..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/README.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# Papertrail Hook for Logrus
-
-[Papertrail](https://papertrailapp.com) provides hosted log management. Once stored in Papertrail, you can [group](http://help.papertrailapp.com/kb/how-it-works/groups/) your logs on various dimensions, [search](http://help.papertrailapp.com/kb/how-it-works/search-syntax) them, and trigger [alerts](http://help.papertrailapp.com/kb/how-it-works/alerts).
-
-In most deployments, you'll want to send logs to Papertrail via their [remote_syslog](http://help.papertrailapp.com/kb/configuration/configuring-centralized-logging-from-text-log-files-in-unix/) daemon, which requires no application-specific configuration. This hook is intended for relatively low-volume logging, likely in managed cloud hosting deployments where installing `remote_syslog` is not possible.
-
-## Usage
-
-You can find your Papertrail UDP port on your [Papertrail account page](https://papertrailapp.com/account/destinations). Substitute it below for `YOUR_PAPERTRAIL_UDP_PORT`.
-
-For `YOUR_APP_NAME`, substitute a short string that will readily identify your application or service in the logs.
-
-```go
-import (
- "log/syslog"
- "github.com/Sirupsen/logrus"
- "github.com/Sirupsen/logrus/hooks/papertrail"
-)
-
-func main() {
- log := logrus.New()
- hook, err := logrus_papertrail.NewPapertrailHook("logs.papertrailapp.com", YOUR_PAPERTRAIL_UDP_PORT, YOUR_APP_NAME)
-
- if err == nil {
- log.Hooks.Add(hook)
- }
-}
-```
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go
deleted file mode 100644
index c0f10c1b..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package logrus_papertrail
-
-import (
- "fmt"
- "net"
- "os"
- "time"
-
- "github.com/Sirupsen/logrus"
-)
-
-const (
- format = "Jan 2 15:04:05"
-)
-
-// PapertrailHook to send logs to a logging service compatible with the Papertrail API.
-type PapertrailHook struct {
- Host string
- Port int
- AppName string
- UDPConn net.Conn
-}
-
-// NewPapertrailHook creates a hook to be added to an instance of logger.
-func NewPapertrailHook(host string, port int, appName string) (*PapertrailHook, error) {
- conn, err := net.Dial("udp", fmt.Sprintf("%s:%d", host, port))
- return &PapertrailHook{host, port, appName, conn}, err
-}
-
-// Fire is called when a log event is fired.
-func (hook *PapertrailHook) Fire(entry *logrus.Entry) error {
- date := time.Now().Format(format)
- msg, _ := entry.String()
- payload := fmt.Sprintf("<22> %s %s: %s", date, hook.AppName, msg)
-
- bytesWritten, err := hook.UDPConn.Write([]byte(payload))
- if err != nil {
- fmt.Fprintf(os.Stderr, "Unable to send log line to Papertrail via UDP. Wrote %d bytes before error: %v", bytesWritten, err)
- return err
- }
-
- return nil
-}
-
-// Levels returns the available logging levels.
-func (hook *PapertrailHook) Levels() []logrus.Level {
- return []logrus.Level{
- logrus.PanicLevel,
- logrus.FatalLevel,
- logrus.ErrorLevel,
- logrus.WarnLevel,
- logrus.InfoLevel,
- logrus.DebugLevel,
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/sentry/README.md b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/sentry/README.md
deleted file mode 100644
index 19e58bb4..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/sentry/README.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# Sentry Hook for Logrus
-
-[Sentry](https://getsentry.com) provides both self-hosted and hosted
-solutions for exception tracking.
-Both client and server are
-[open source](https://github.com/getsentry/sentry).
-
-## Usage
-
-Every sentry application defined on the server gets a different
-[DSN](https://www.getsentry.com/docs/). In the example below replace
-`YOUR_DSN` with the one created for your application.
-
-```go
-import (
- "github.com/Sirupsen/logrus"
- "github.com/Sirupsen/logrus/hooks/sentry"
-)
-
-func main() {
- log := logrus.New()
- hook, err := logrus_sentry.NewSentryHook(YOUR_DSN, []logrus.Level{
- logrus.PanicLevel,
- logrus.FatalLevel,
- logrus.ErrorLevel,
- })
-
- if err == nil {
- log.Hooks.Add(hook)
- }
-}
-```
-
-## Special fields
-
-Some logrus fields have a special meaning in this hook,
-these are server_name and logger.
-When logs are sent to sentry these fields are treated differently.
-- server_name (also known as hostname) is the name of the server which
-is logging the event (hostname.example.com)
-- logger is the part of the application which is logging the event.
-In go this usually means setting it to the name of the package.
-
-## Timeout
-
-`Timeout` is the time the sentry hook will wait for a response
-from the sentry server.
-
-If this time elapses with no response from
-the server an error will be returned.
-
-If `Timeout` is set to 0 the SentryHook will not wait for a reply
-and will assume a correct delivery.
-
-The SentryHook has a default timeout of `100 milliseconds` when created
-with a call to `NewSentryHook`. This can be changed by assigning a value to the `Timeout` field:
-
-```go
-hook, _ := logrus_sentry.NewSentryHook(...)
-hook.Timeout = 20*time.Second
-```
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/sentry/sentry.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/sentry/sentry.go
deleted file mode 100644
index 379f281c..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/sentry/sentry.go
+++ /dev/null
@@ -1,100 +0,0 @@
-package logrus_sentry
-
-import (
- "fmt"
- "time"
-
- "github.com/Sirupsen/logrus"
- "github.com/getsentry/raven-go"
-)
-
-var (
- severityMap = map[logrus.Level]raven.Severity{
- logrus.DebugLevel: raven.DEBUG,
- logrus.InfoLevel: raven.INFO,
- logrus.WarnLevel: raven.WARNING,
- logrus.ErrorLevel: raven.ERROR,
- logrus.FatalLevel: raven.FATAL,
- logrus.PanicLevel: raven.FATAL,
- }
-)
-
-func getAndDel(d logrus.Fields, key string) (string, bool) {
- var (
- ok bool
- v interface{}
- val string
- )
- if v, ok = d[key]; !ok {
- return "", false
- }
-
- if val, ok = v.(string); !ok {
- return "", false
- }
- delete(d, key)
- return val, true
-}
-
-// SentryHook delivers logs to a sentry server.
-type SentryHook struct {
- // Timeout sets the time to wait for a delivery error from the sentry server.
- // If this is set to zero the server will not wait for any response and will
- // consider the message correctly sent
- Timeout time.Duration
-
- client *raven.Client
- levels []logrus.Level
-}
-
-// NewSentryHook creates a hook to be added to an instance of logger
-// and initializes the raven client.
-// This method sets the timeout to 100 milliseconds.
-func NewSentryHook(DSN string, levels []logrus.Level) (*SentryHook, error) {
- client, err := raven.NewClient(DSN, nil)
- if err != nil {
- return nil, err
- }
- return &SentryHook{100 * time.Millisecond, client, levels}, nil
-}
-
-// Called when an event should be sent to sentry
-// Special fields that sentry uses to give more information to the server
-// are extracted from entry.Data (if they are found)
-// These fields are: logger and server_name
-func (hook *SentryHook) Fire(entry *logrus.Entry) error {
- packet := &raven.Packet{
- Message: entry.Message,
- Timestamp: raven.Timestamp(entry.Time),
- Level: severityMap[entry.Level],
- Platform: "go",
- }
-
- d := entry.Data
-
- if logger, ok := getAndDel(d, "logger"); ok {
- packet.Logger = logger
- }
- if serverName, ok := getAndDel(d, "server_name"); ok {
- packet.ServerName = serverName
- }
- packet.Extra = map[string]interface{}(d)
-
- _, errCh := hook.client.Capture(packet, nil)
- timeout := hook.Timeout
- if timeout != 0 {
- timeoutCh := time.After(timeout)
- select {
- case err := <-errCh:
- return err
- case <-timeoutCh:
- return fmt.Errorf("no response from sentry server in %s", timeout)
- }
- }
- return nil
-}
-
-// Levels returns the available logging levels.
-func (hook *SentryHook) Levels() []logrus.Level {
- return hook.levels
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/README.md b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/README.md
deleted file mode 100644
index 4dbb8e72..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/README.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# Syslog Hooks for Logrus
-
-## Usage
-
-```go
-import (
- "log/syslog"
- "github.com/Sirupsen/logrus"
- logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
-)
-
-func main() {
- log := logrus.New()
- hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
-
- if err == nil {
- log.Hooks.Add(hook)
- }
-}
-```
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog.go
deleted file mode 100644
index b6fa3746..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package logrus_syslog
-
-import (
- "fmt"
- "github.com/Sirupsen/logrus"
- "log/syslog"
- "os"
-)
-
-// SyslogHook to send logs via syslog.
-type SyslogHook struct {
- Writer *syslog.Writer
- SyslogNetwork string
- SyslogRaddr string
-}
-
-// Creates a hook to be added to an instance of logger. This is called with
-// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")`
-// `if err == nil { log.Hooks.Add(hook) }`
-func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
- w, err := syslog.Dial(network, raddr, priority, tag)
- return &SyslogHook{w, network, raddr}, err
-}
-
-func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
- line, err := entry.String()
- if err != nil {
- fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
- return err
- }
-
- switch entry.Level {
- case logrus.PanicLevel:
- return hook.Writer.Crit(line)
- case logrus.FatalLevel:
- return hook.Writer.Crit(line)
- case logrus.ErrorLevel:
- return hook.Writer.Err(line)
- case logrus.WarnLevel:
- return hook.Writer.Warning(line)
- case logrus.InfoLevel:
- return hook.Writer.Info(line)
- case logrus.DebugLevel:
- return hook.Writer.Debug(line)
- default:
- return nil
- }
-}
-
-func (hook *SyslogHook) Levels() []logrus.Level {
- return []logrus.Level{
- logrus.PanicLevel,
- logrus.FatalLevel,
- logrus.ErrorLevel,
- logrus.WarnLevel,
- logrus.InfoLevel,
- logrus.DebugLevel,
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/json_formatter.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/json_formatter.go
deleted file mode 100644
index dcc4f1d9..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/json_formatter.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package logrus
-
-import (
- "encoding/json"
- "fmt"
-)
-
-type JSONFormatter struct {
- // TimestampFormat sets the format used for marshaling timestamps.
- TimestampFormat string
-}
-
-func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
- data := make(Fields, len(entry.Data)+3)
- for k, v := range entry.Data {
- switch v := v.(type) {
- case error:
- // Otherwise errors are ignored by `encoding/json`
- // https://github.com/Sirupsen/logrus/issues/137
- data[k] = v.Error()
- default:
- data[k] = v
- }
- }
- prefixFieldClashes(data)
-
- if f.TimestampFormat == "" {
- f.TimestampFormat = DefaultTimestampFormat
- }
-
- data["time"] = entry.Time.Format(f.TimestampFormat)
- data["msg"] = entry.Message
- data["level"] = entry.Level.String()
-
- serialized, err := json.Marshal(data)
- if err != nil {
- return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
- }
- return append(serialized, '\n'), nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/logger.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/logger.go
deleted file mode 100644
index da928a37..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/logger.go
+++ /dev/null
@@ -1,203 +0,0 @@
-package logrus
-
-import (
- "io"
- "os"
- "sync"
-)
-
-type Logger struct {
- // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
- // file, or leave it default which is `os.Stdout`. You can also set this to
- // something more adventorous, such as logging to Kafka.
- Out io.Writer
- // Hooks for the logger instance. These allow firing events based on logging
- // levels and log entries. For example, to send errors to an error tracking
- // service, log to StatsD or dump the core on fatal errors.
- Hooks levelHooks
- // All log entries pass through the formatter before logged to Out. The
- // included formatters are `TextFormatter` and `JSONFormatter` for which
- // TextFormatter is the default. In development (when a TTY is attached) it
- // logs with colors, but to a file it wouldn't. You can easily implement your
- // own that implements the `Formatter` interface, see the `README` or included
- // formatters for examples.
- Formatter Formatter
- // The logging level the logger should log at. This is typically (and defaults
- // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
- // logged. `logrus.Debug` is useful in
- Level Level
- // Used to sync writing to the log.
- mu sync.Mutex
-}
-
-// Creates a new logger. Configuration should be set by changing `Formatter`,
-// `Out` and `Hooks` directly on the default logger instance. You can also just
-// instantiate your own:
-//
-// var log = &Logger{
-// Out: os.Stderr,
-// Formatter: new(JSONFormatter),
-// Hooks: make(levelHooks),
-// Level: logrus.DebugLevel,
-// }
-//
-// It's recommended to make this a global instance called `log`.
-func New() *Logger {
- return &Logger{
- Out: os.Stdout,
- Formatter: new(TextFormatter),
- Hooks: make(levelHooks),
- Level: InfoLevel,
- }
-}
-
-// Adds a field to the log entry, note that you it doesn't log until you call
-// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry.
-// Ff you want multiple fields, use `WithFields`.
-func (logger *Logger) WithField(key string, value interface{}) *Entry {
- return NewEntry(logger).WithField(key, value)
-}
-
-// Adds a struct of fields to the log entry. All it does is call `WithField` for
-// each `Field`.
-func (logger *Logger) WithFields(fields Fields) *Entry {
- return NewEntry(logger).WithFields(fields)
-}
-
-func (logger *Logger) Debugf(format string, args ...interface{}) {
- if logger.Level >= DebugLevel {
- NewEntry(logger).Debugf(format, args...)
- }
-}
-
-func (logger *Logger) Infof(format string, args ...interface{}) {
- if logger.Level >= InfoLevel {
- NewEntry(logger).Infof(format, args...)
- }
-}
-
-func (logger *Logger) Printf(format string, args ...interface{}) {
- NewEntry(logger).Printf(format, args...)
-}
-
-func (logger *Logger) Warnf(format string, args ...interface{}) {
- if logger.Level >= WarnLevel {
- NewEntry(logger).Warnf(format, args...)
- }
-}
-
-func (logger *Logger) Warningf(format string, args ...interface{}) {
- if logger.Level >= WarnLevel {
- NewEntry(logger).Warnf(format, args...)
- }
-}
-
-func (logger *Logger) Errorf(format string, args ...interface{}) {
- if logger.Level >= ErrorLevel {
- NewEntry(logger).Errorf(format, args...)
- }
-}
-
-func (logger *Logger) Fatalf(format string, args ...interface{}) {
- if logger.Level >= FatalLevel {
- NewEntry(logger).Fatalf(format, args...)
- }
-}
-
-func (logger *Logger) Panicf(format string, args ...interface{}) {
- if logger.Level >= PanicLevel {
- NewEntry(logger).Panicf(format, args...)
- }
-}
-
-func (logger *Logger) Debug(args ...interface{}) {
- if logger.Level >= DebugLevel {
- NewEntry(logger).Debug(args...)
- }
-}
-
-func (logger *Logger) Info(args ...interface{}) {
- if logger.Level >= InfoLevel {
- NewEntry(logger).Info(args...)
- }
-}
-
-func (logger *Logger) Print(args ...interface{}) {
- NewEntry(logger).Info(args...)
-}
-
-func (logger *Logger) Warn(args ...interface{}) {
- if logger.Level >= WarnLevel {
- NewEntry(logger).Warn(args...)
- }
-}
-
-func (logger *Logger) Warning(args ...interface{}) {
- if logger.Level >= WarnLevel {
- NewEntry(logger).Warn(args...)
- }
-}
-
-func (logger *Logger) Error(args ...interface{}) {
- if logger.Level >= ErrorLevel {
- NewEntry(logger).Error(args...)
- }
-}
-
-func (logger *Logger) Fatal(args ...interface{}) {
- if logger.Level >= FatalLevel {
- NewEntry(logger).Fatal(args...)
- }
-}
-
-func (logger *Logger) Panic(args ...interface{}) {
- if logger.Level >= PanicLevel {
- NewEntry(logger).Panic(args...)
- }
-}
-
-func (logger *Logger) Debugln(args ...interface{}) {
- if logger.Level >= DebugLevel {
- NewEntry(logger).Debugln(args...)
- }
-}
-
-func (logger *Logger) Infoln(args ...interface{}) {
- if logger.Level >= InfoLevel {
- NewEntry(logger).Infoln(args...)
- }
-}
-
-func (logger *Logger) Println(args ...interface{}) {
- NewEntry(logger).Println(args...)
-}
-
-func (logger *Logger) Warnln(args ...interface{}) {
- if logger.Level >= WarnLevel {
- NewEntry(logger).Warnln(args...)
- }
-}
-
-func (logger *Logger) Warningln(args ...interface{}) {
- if logger.Level >= WarnLevel {
- NewEntry(logger).Warnln(args...)
- }
-}
-
-func (logger *Logger) Errorln(args ...interface{}) {
- if logger.Level >= ErrorLevel {
- NewEntry(logger).Errorln(args...)
- }
-}
-
-func (logger *Logger) Fatalln(args ...interface{}) {
- if logger.Level >= FatalLevel {
- NewEntry(logger).Fatalln(args...)
- }
-}
-
-func (logger *Logger) Panicln(args ...interface{}) {
- if logger.Level >= PanicLevel {
- NewEntry(logger).Panicln(args...)
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/logrus.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/logrus.go
deleted file mode 100644
index 43ee12e9..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/logrus.go
+++ /dev/null
@@ -1,94 +0,0 @@
-package logrus
-
-import (
- "fmt"
- "log"
-)
-
-// Fields type, used to pass to `WithFields`.
-type Fields map[string]interface{}
-
-// Level type
-type Level uint8
-
-// Convert the Level to a string. E.g. PanicLevel becomes "panic".
-func (level Level) String() string {
- switch level {
- case DebugLevel:
- return "debug"
- case InfoLevel:
- return "info"
- case WarnLevel:
- return "warning"
- case ErrorLevel:
- return "error"
- case FatalLevel:
- return "fatal"
- case PanicLevel:
- return "panic"
- }
-
- return "unknown"
-}
-
-// ParseLevel takes a string level and returns the Logrus log level constant.
-func ParseLevel(lvl string) (Level, error) {
- switch lvl {
- case "panic":
- return PanicLevel, nil
- case "fatal":
- return FatalLevel, nil
- case "error":
- return ErrorLevel, nil
- case "warn", "warning":
- return WarnLevel, nil
- case "info":
- return InfoLevel, nil
- case "debug":
- return DebugLevel, nil
- }
-
- var l Level
- return l, fmt.Errorf("not a valid logrus Level: %q", lvl)
-}
-
-// These are the different logging levels. You can set the logging level to log
-// on your instance of logger, obtained with `logrus.New()`.
-const (
- // PanicLevel level, highest level of severity. Logs and then calls panic with the
- // message passed to Debug, Info, ...
- PanicLevel Level = iota
- // FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the
- // logging level is set to Panic.
- FatalLevel
- // ErrorLevel level. Logs. Used for errors that should definitely be noted.
- // Commonly used for hooks to send errors to an error tracking service.
- ErrorLevel
- // WarnLevel level. Non-critical entries that deserve eyes.
- WarnLevel
- // InfoLevel level. General operational entries about what's going on inside the
- // application.
- InfoLevel
- // DebugLevel level. Usually only enabled when debugging. Very verbose logging.
- DebugLevel
-)
-
-// Won't compile if StdLogger can't be realized by a log.Logger
-var _ StdLogger = &log.Logger{}
-
-// StdLogger is what your logrus-enabled library should take, that way
-// it'll accept a stdlib logger and a logrus logger. There's no standard
-// interface, this is the closest we get, unfortunately.
-type StdLogger interface {
- Print(...interface{})
- Printf(string, ...interface{})
- Println(...interface{})
-
- Fatal(...interface{})
- Fatalf(string, ...interface{})
- Fatalln(...interface{})
-
- Panic(...interface{})
- Panicf(string, ...interface{})
- Panicln(...interface{})
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_darwin.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_darwin.go
deleted file mode 100644
index 8fe02a4a..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_darwin.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Based on ssh/terminal:
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package logrus
-
-import "syscall"
-
-const ioctlReadTermios = syscall.TIOCGETA
-
-type Termios syscall.Termios
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_freebsd.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_freebsd.go
deleted file mode 100644
index 0428ee5d..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_freebsd.go
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- Go 1.2 doesn't include Termios for FreeBSD. This should be added in 1.3 and this could be merged with terminal_darwin.
-*/
-package logrus
-
-import (
- "syscall"
-)
-
-const ioctlReadTermios = syscall.TIOCGETA
-
-type Termios struct {
- Iflag uint32
- Oflag uint32
- Cflag uint32
- Lflag uint32
- Cc [20]uint8
- Ispeed uint32
- Ospeed uint32
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_linux.go
deleted file mode 100644
index a2c0b40d..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_linux.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Based on ssh/terminal:
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package logrus
-
-import "syscall"
-
-const ioctlReadTermios = syscall.TCGETS
-
-type Termios syscall.Termios
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_notwindows.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_notwindows.go
deleted file mode 100644
index b8bebc13..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_notwindows.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Based on ssh/terminal:
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build linux darwin freebsd openbsd
-
-package logrus
-
-import (
- "syscall"
- "unsafe"
-)
-
-// IsTerminal returns true if the given file descriptor is a terminal.
-func IsTerminal() bool {
- fd := syscall.Stdout
- var termios Termios
- _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
- return err == 0
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_openbsd.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_openbsd.go
deleted file mode 100644
index af609a53..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_openbsd.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package logrus
-
-import "syscall"
-
-const ioctlReadTermios = syscall.TIOCGETA
-
-type Termios syscall.Termios
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_windows.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_windows.go
deleted file mode 100644
index 2e09f6f7..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_windows.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Based on ssh/terminal:
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build windows
-
-package logrus
-
-import (
- "syscall"
- "unsafe"
-)
-
-var kernel32 = syscall.NewLazyDLL("kernel32.dll")
-
-var (
- procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
-)
-
-// IsTerminal returns true if the given file descriptor is a terminal.
-func IsTerminal() bool {
- fd := syscall.Stdout
- var st uint32
- r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
- return r != 0 && e == 0
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/text_formatter.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/text_formatter.go
deleted file mode 100644
index 612417ff..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/text_formatter.go
+++ /dev/null
@@ -1,149 +0,0 @@
-package logrus
-
-import (
- "bytes"
- "fmt"
- "sort"
- "strings"
- "time"
-)
-
-const (
- nocolor = 0
- red = 31
- green = 32
- yellow = 33
- blue = 34
- gray = 37
-)
-
-var (
- baseTimestamp time.Time
- isTerminal bool
-)
-
-func init() {
- baseTimestamp = time.Now()
- isTerminal = IsTerminal()
-}
-
-func miniTS() int {
- return int(time.Since(baseTimestamp) / time.Second)
-}
-
-type TextFormatter struct {
- // Set to true to bypass checking for a TTY before outputting colors.
- ForceColors bool
-
- // Force disabling colors.
- DisableColors bool
-
- // Disable timestamp logging. useful when output is redirected to logging
- // system that already adds timestamps.
- DisableTimestamp bool
-
- // Enable logging the full timestamp when a TTY is attached instead of just
- // the time passed since beginning of execution.
- FullTimestamp bool
-
- // TimestampFormat to use for display when a full timestamp is printed
- TimestampFormat string
-
- // The fields are sorted by default for a consistent output. For applications
- // that log extremely frequently and don't use the JSON formatter this may not
- // be desired.
- DisableSorting bool
-}
-
-func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
- var keys []string = make([]string, 0, len(entry.Data))
- for k := range entry.Data {
- keys = append(keys, k)
- }
-
- if !f.DisableSorting {
- sort.Strings(keys)
- }
-
- b := &bytes.Buffer{}
-
- prefixFieldClashes(entry.Data)
-
- isColored := (f.ForceColors || isTerminal) && !f.DisableColors
-
- if f.TimestampFormat == "" {
- f.TimestampFormat = DefaultTimestampFormat
- }
- if isColored {
- f.printColored(b, entry, keys)
- } else {
- if !f.DisableTimestamp {
- f.appendKeyValue(b, "time", entry.Time.Format(f.TimestampFormat))
- }
- f.appendKeyValue(b, "level", entry.Level.String())
- f.appendKeyValue(b, "msg", entry.Message)
- for _, key := range keys {
- f.appendKeyValue(b, key, entry.Data[key])
- }
- }
-
- b.WriteByte('\n')
- return b.Bytes(), nil
-}
-
-func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string) {
- var levelColor int
- switch entry.Level {
- case DebugLevel:
- levelColor = gray
- case WarnLevel:
- levelColor = yellow
- case ErrorLevel, FatalLevel, PanicLevel:
- levelColor = red
- default:
- levelColor = blue
- }
-
- levelText := strings.ToUpper(entry.Level.String())[0:4]
-
- if !f.FullTimestamp {
- fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message)
- } else {
- fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(f.TimestampFormat), entry.Message)
- }
- for _, k := range keys {
- v := entry.Data[k]
- fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%v", levelColor, k, v)
- }
-}
-
-func needsQuoting(text string) bool {
- for _, ch := range text {
- if !((ch >= 'a' && ch <= 'z') ||
- (ch >= 'A' && ch <= 'Z') ||
- (ch >= '0' && ch <= '9') ||
- ch == '-' || ch == '.') {
- return false
- }
- }
- return true
-}
-
-func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key, value interface{}) {
- switch value.(type) {
- case string:
- if needsQuoting(value.(string)) {
- fmt.Fprintf(b, "%v=%s ", key, value)
- } else {
- fmt.Fprintf(b, "%v=%q ", key, value)
- }
- case error:
- if needsQuoting(value.(error).Error()) {
- fmt.Fprintf(b, "%v=%s ", key, value)
- } else {
- fmt.Fprintf(b, "%v=%q ", key, value)
- }
- default:
- fmt.Fprintf(b, "%v=%v ", key, value)
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/writer.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/writer.go
deleted file mode 100644
index 1e30b1c7..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/Sirupsen/logrus/writer.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package logrus
-
-import (
- "bufio"
- "io"
- "runtime"
-)
-
-func (logger *Logger) Writer() *io.PipeWriter {
- reader, writer := io.Pipe()
-
- go logger.writerScanner(reader)
- runtime.SetFinalizer(writer, writerFinalizer)
-
- return writer
-}
-
-func (logger *Logger) writerScanner(reader *io.PipeReader) {
- scanner := bufio.NewScanner(reader)
- for scanner.Scan() {
- logger.Print(scanner.Text())
- }
- if err := scanner.Err(); err != nil {
- logger.Errorf("Error while reading from Writer: %s", err)
- }
- reader.Close()
-}
-
-func writerFinalizer(writer *io.PipeWriter) {
- writer.Close()
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/.travis.yml b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/.travis.yml
deleted file mode 100644
index 87ba52f9..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/.travis.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-language: go
-sudo: false
-
-go:
-- 1.0.3
-- 1.1.2
-- 1.2.2
-- 1.3.3
-- 1.4.2
-- 1.5.1
-- tip
-
-matrix:
- allow_failures:
- - go: tip
-
-script:
-- go vet ./...
-- go test -v ./...
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/LICENSE b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/LICENSE
deleted file mode 100644
index 5515ccfb..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-Copyright (C) 2013 Jeremy Saenz
-All Rights Reserved.
-
-MIT LICENSE
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/README.md b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/README.md
deleted file mode 100644
index 4f5f954b..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/README.md
+++ /dev/null
@@ -1,341 +0,0 @@
-[![Coverage](http://gocover.io/_badge/github.com/codegangsta/cli?0)](http://gocover.io/github.com/codegangsta/cli)
-[![Build Status](https://travis-ci.org/codegangsta/cli.png?branch=master)](https://travis-ci.org/codegangsta/cli)
-[![GoDoc](https://godoc.org/github.com/codegangsta/cli?status.svg)](https://godoc.org/github.com/codegangsta/cli)
-
-# cli.go
-`cli.go` is simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable command line applications in an expressive way.
-
-## Overview
-Command line apps are usually so tiny that there is absolutely no reason why your code should *not* be self-documenting. Things like generating help text and parsing command flags/options should not hinder productivity when writing a command line app.
-
-**This is where `cli.go` comes into play.** `cli.go` makes command line programming fun, organized, and expressive!
-
-## Installation
-Make sure you have a working Go environment (go 1.1+ is *required*). [See the install instructions](http://golang.org/doc/install.html).
-
-To install `cli.go`, simply run:
-```
-$ go get github.com/codegangsta/cli
-```
-
-Make sure your `PATH` includes to the `$GOPATH/bin` directory so your commands can be easily used:
-```
-export PATH=$PATH:$GOPATH/bin
-```
-
-## Getting Started
-One of the philosophies behind `cli.go` is that an API should be playful and full of discovery. So a `cli.go` app can be as little as one line of code in `main()`.
-
-``` go
-package main
-
-import (
- "os"
- "github.com/codegangsta/cli"
-)
-
-func main() {
- cli.NewApp().Run(os.Args)
-}
-```
-
-This app will run and show help text, but is not very useful. Let's give an action to execute and some help documentation:
-
-``` go
-package main
-
-import (
- "os"
- "github.com/codegangsta/cli"
-)
-
-func main() {
- app := cli.NewApp()
- app.Name = "boom"
- app.Usage = "make an explosive entrance"
- app.Action = func(c *cli.Context) {
- println("boom! I say!")
- }
-
- app.Run(os.Args)
-}
-```
-
-Running this already gives you a ton of functionality, plus support for things like subcommands and flags, which are covered below.
-
-## Example
-
-Being a programmer can be a lonely job. Thankfully by the power of automation that is not the case! Let's create a greeter app to fend off our demons of loneliness!
-
-Start by creating a directory named `greet`, and within it, add a file, `greet.go` with the following code in it:
-
-``` go
-package main
-
-import (
- "os"
- "github.com/codegangsta/cli"
-)
-
-func main() {
- app := cli.NewApp()
- app.Name = "greet"
- app.Usage = "fight the loneliness!"
- app.Action = func(c *cli.Context) {
- println("Hello friend!")
- }
-
- app.Run(os.Args)
-}
-```
-
-Install our command to the `$GOPATH/bin` directory:
-
-```
-$ go install
-```
-
-Finally run our new command:
-
-```
-$ greet
-Hello friend!
-```
-
-`cli.go` also generates neat help text:
-
-```
-$ greet help
-NAME:
- greet - fight the loneliness!
-
-USAGE:
- greet [global options] command [command options] [arguments...]
-
-VERSION:
- 0.0.0
-
-COMMANDS:
- help, h Shows a list of commands or help for one command
-
-GLOBAL OPTIONS
- --version Shows version information
-```
-
-### Arguments
-You can lookup arguments by calling the `Args` function on `cli.Context`.
-
-``` go
-...
-app.Action = func(c *cli.Context) {
- println("Hello", c.Args()[0])
-}
-...
-```
-
-### Flags
-Setting and querying flags is simple.
-``` go
-...
-app.Flags = []cli.Flag {
- cli.StringFlag{
- Name: "lang",
- Value: "english",
- Usage: "language for the greeting",
- },
-}
-app.Action = func(c *cli.Context) {
- name := "someone"
- if len(c.Args()) > 0 {
- name = c.Args()[0]
- }
- if c.String("lang") == "spanish" {
- println("Hola", name)
- } else {
- println("Hello", name)
- }
-}
-...
-```
-
-You can also set a destination variable for a flag, to which the content will be scanned.
-``` go
-...
-var language string
-app.Flags = []cli.Flag {
- cli.StringFlag{
- Name: "lang",
- Value: "english",
- Usage: "language for the greeting",
- Destination: &language,
- },
-}
-app.Action = func(c *cli.Context) {
- name := "someone"
- if len(c.Args()) > 0 {
- name = c.Args()[0]
- }
- if language == "spanish" {
- println("Hola", name)
- } else {
- println("Hello", name)
- }
-}
-...
-```
-
-See full list of flags at http://godoc.org/github.com/codegangsta/cli
-
-#### Alternate Names
-
-You can set alternate (or short) names for flags by providing a comma-delimited list for the `Name`. e.g.
-
-``` go
-app.Flags = []cli.Flag {
- cli.StringFlag{
- Name: "lang, l",
- Value: "english",
- Usage: "language for the greeting",
- },
-}
-```
-
-That flag can then be set with `--lang spanish` or `-l spanish`. Note that giving two different forms of the same flag in the same command invocation is an error.
-
-#### Values from the Environment
-
-You can also have the default value set from the environment via `EnvVar`. e.g.
-
-``` go
-app.Flags = []cli.Flag {
- cli.StringFlag{
- Name: "lang, l",
- Value: "english",
- Usage: "language for the greeting",
- EnvVar: "APP_LANG",
- },
-}
-```
-
-The `EnvVar` may also be given as a comma-delimited "cascade", where the first environment variable that resolves is used as the default.
-
-``` go
-app.Flags = []cli.Flag {
- cli.StringFlag{
- Name: "lang, l",
- Value: "english",
- Usage: "language for the greeting",
- EnvVar: "LEGACY_COMPAT_LANG,APP_LANG,LANG",
- },
-}
-```
-
-### Subcommands
-
-Subcommands can be defined for a more git-like command line app.
-```go
-...
-app.Commands = []cli.Command{
- {
- Name: "add",
- Aliases: []string{"a"},
- Usage: "add a task to the list",
- Action: func(c *cli.Context) {
- println("added task: ", c.Args().First())
- },
- },
- {
- Name: "complete",
- Aliases: []string{"c"},
- Usage: "complete a task on the list",
- Action: func(c *cli.Context) {
- println("completed task: ", c.Args().First())
- },
- },
- {
- Name: "template",
- Aliases: []string{"r"},
- Usage: "options for task templates",
- Subcommands: []cli.Command{
- {
- Name: "add",
- Usage: "add a new template",
- Action: func(c *cli.Context) {
- println("new task template: ", c.Args().First())
- },
- },
- {
- Name: "remove",
- Usage: "remove an existing template",
- Action: func(c *cli.Context) {
- println("removed task template: ", c.Args().First())
- },
- },
- },
- },
-}
-...
-```
-
-### Bash Completion
-
-You can enable completion commands by setting the `EnableBashCompletion`
-flag on the `App` object. By default, this setting will only auto-complete to
-show an app's subcommands, but you can write your own completion methods for
-the App or its subcommands.
-```go
-...
-var tasks = []string{"cook", "clean", "laundry", "eat", "sleep", "code"}
-app := cli.NewApp()
-app.EnableBashCompletion = true
-app.Commands = []cli.Command{
- {
- Name: "complete",
- Aliases: []string{"c"},
- Usage: "complete a task on the list",
- Action: func(c *cli.Context) {
- println("completed task: ", c.Args().First())
- },
- BashComplete: func(c *cli.Context) {
- // This will complete if no args are passed
- if len(c.Args()) > 0 {
- return
- }
- for _, t := range tasks {
- fmt.Println(t)
- }
- },
- }
-}
-...
-```
-
-#### To Enable
-
-Source the `autocomplete/bash_autocomplete` file in your `.bashrc` file while
-setting the `PROG` variable to the name of your program:
-
-`PROG=myprogram source /.../cli/autocomplete/bash_autocomplete`
-
-#### To Distribute
-
-Copy `autocomplete/bash_autocomplete` into `/etc/bash_completion.d/` and rename
-it to the name of the program you wish to add autocomplete support for (or
-automatically install it there if you are distributing a package). Don't forget
-to source the file to make it active in the current shell.
-
-```
- sudo cp src/bash_autocomplete /etc/bash_completion.d/
- source /etc/bash_completion.d/
-```
-
-Alternatively, you can just document that users should source the generic
-`autocomplete/bash_autocomplete` in their bash configuration with `$PROG` set
-to the name of their program (as above).
-
-## Contribution Guidelines
-Feel free to put up a pull request to fix a bug or maybe add a feature. I will give it a code review and make sure that it does not break backwards compatibility. If I or any other collaborators agree that it is in line with the vision of the project, we will work with you to get the code into a mergeable state and merge it into the master branch.
-
-If you have contributed something significant to the project, I will most likely add you as a collaborator. As a collaborator you are given the ability to merge others pull requests. It is very important that new code does not break existing code, so be careful about what code you do choose to merge. If you have any questions feel free to link @codegangsta to the issue in question and we can review it together.
-
-If you feel like you have contributed to the project but have not yet been added as a collaborator, I probably forgot to add you. Hit @codegangsta up over email and we will get it figured out.
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/app.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/app.go
deleted file mode 100644
index 2f992d0d..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/app.go
+++ /dev/null
@@ -1,334 +0,0 @@
-package cli
-
-import (
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "path"
- "time"
-)
-
-// App is the main structure of a cli application. It is recomended that
-// an app be created with the cli.NewApp() function
-type App struct {
- // The name of the program. Defaults to path.Base(os.Args[0])
- Name string
- // Full name of command for help, defaults to Name
- HelpName string
- // Description of the program.
- Usage string
- // Description of the program argument format.
- ArgsUsage string
- // Version of the program
- Version string
- // List of commands to execute
- Commands []Command
- // List of flags to parse
- Flags []Flag
- // Boolean to enable bash completion commands
- EnableBashCompletion bool
- // Boolean to hide built-in help command
- HideHelp bool
- // Boolean to hide built-in version flag
- HideVersion bool
- // An action to execute when the bash-completion flag is set
- BashComplete func(context *Context)
- // An action to execute before any subcommands are run, but after the context is ready
- // If a non-nil error is returned, no subcommands are run
- Before func(context *Context) error
- // An action to execute after any subcommands are run, but after the subcommand has finished
- // It is run even if Action() panics
- After func(context *Context) error
- // The action to execute when no subcommands are specified
- Action func(context *Context)
- // Execute this function if the proper command cannot be found
- CommandNotFound func(context *Context, command string)
- // Compilation date
- Compiled time.Time
- // List of all authors who contributed
- Authors []Author
- // Copyright of the binary if any
- Copyright string
- // Name of Author (Note: Use App.Authors, this is deprecated)
- Author string
- // Email of Author (Note: Use App.Authors, this is deprecated)
- Email string
- // Writer writer to write output to
- Writer io.Writer
-}
-
-// Tries to find out when this binary was compiled.
-// Returns the current time if it fails to find it.
-func compileTime() time.Time {
- info, err := os.Stat(os.Args[0])
- if err != nil {
- return time.Now()
- }
- return info.ModTime()
-}
-
-// Creates a new cli Application with some reasonable defaults for Name, Usage, Version and Action.
-func NewApp() *App {
- return &App{
- Name: path.Base(os.Args[0]),
- HelpName: path.Base(os.Args[0]),
- Usage: "A new cli application",
- Version: "0.0.0",
- BashComplete: DefaultAppComplete,
- Action: helpCommand.Action,
- Compiled: compileTime(),
- Writer: os.Stdout,
- }
-}
-
-// Entry point to the cli app. Parses the arguments slice and routes to the proper flag/args combination
-func (a *App) Run(arguments []string) (err error) {
- if a.Author != "" || a.Email != "" {
- a.Authors = append(a.Authors, Author{Name: a.Author, Email: a.Email})
- }
-
- newCmds := []Command{}
- for _, c := range a.Commands {
- if c.HelpName == "" {
- c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name)
- }
- newCmds = append(newCmds, c)
- }
- a.Commands = newCmds
-
- // append help to commands
- if a.Command(helpCommand.Name) == nil && !a.HideHelp {
- a.Commands = append(a.Commands, helpCommand)
- if (HelpFlag != BoolFlag{}) {
- a.appendFlag(HelpFlag)
- }
- }
-
- //append version/help flags
- if a.EnableBashCompletion {
- a.appendFlag(BashCompletionFlag)
- }
-
- if !a.HideVersion {
- a.appendFlag(VersionFlag)
- }
-
- // parse flags
- set := flagSet(a.Name, a.Flags)
- set.SetOutput(ioutil.Discard)
- err = set.Parse(arguments[1:])
- nerr := normalizeFlags(a.Flags, set)
- if nerr != nil {
- fmt.Fprintln(a.Writer, nerr)
- context := NewContext(a, set, nil)
- ShowAppHelp(context)
- return nerr
- }
- context := NewContext(a, set, nil)
-
- if checkCompletions(context) {
- return nil
- }
-
- if err != nil {
- fmt.Fprintln(a.Writer, "Incorrect Usage.")
- fmt.Fprintln(a.Writer)
- ShowAppHelp(context)
- return err
- }
-
- if !a.HideHelp && checkHelp(context) {
- ShowAppHelp(context)
- return nil
- }
-
- if !a.HideVersion && checkVersion(context) {
- ShowVersion(context)
- return nil
- }
-
- if a.After != nil {
- defer func() {
- afterErr := a.After(context)
- if afterErr != nil {
- if err != nil {
- err = NewMultiError(err, afterErr)
- } else {
- err = afterErr
- }
- }
- }()
- }
-
- if a.Before != nil {
- err := a.Before(context)
- if err != nil {
- return err
- }
- }
-
- args := context.Args()
- if args.Present() {
- name := args.First()
- c := a.Command(name)
- if c != nil {
- return c.Run(context)
- }
- }
-
- // Run default Action
- a.Action(context)
- return nil
-}
-
-// Another entry point to the cli app, takes care of passing arguments and error handling
-func (a *App) RunAndExitOnError() {
- if err := a.Run(os.Args); err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
-}
-
-// Invokes the subcommand given the context, parses ctx.Args() to generate command-specific flags
-func (a *App) RunAsSubcommand(ctx *Context) (err error) {
- // append help to commands
- if len(a.Commands) > 0 {
- if a.Command(helpCommand.Name) == nil && !a.HideHelp {
- a.Commands = append(a.Commands, helpCommand)
- if (HelpFlag != BoolFlag{}) {
- a.appendFlag(HelpFlag)
- }
- }
- }
-
- newCmds := []Command{}
- for _, c := range a.Commands {
- if c.HelpName == "" {
- c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name)
- }
- newCmds = append(newCmds, c)
- }
- a.Commands = newCmds
-
- // append flags
- if a.EnableBashCompletion {
- a.appendFlag(BashCompletionFlag)
- }
-
- // parse flags
- set := flagSet(a.Name, a.Flags)
- set.SetOutput(ioutil.Discard)
- err = set.Parse(ctx.Args().Tail())
- nerr := normalizeFlags(a.Flags, set)
- context := NewContext(a, set, ctx)
-
- if nerr != nil {
- fmt.Fprintln(a.Writer, nerr)
- fmt.Fprintln(a.Writer)
- if len(a.Commands) > 0 {
- ShowSubcommandHelp(context)
- } else {
- ShowCommandHelp(ctx, context.Args().First())
- }
- return nerr
- }
-
- if checkCompletions(context) {
- return nil
- }
-
- if err != nil {
- fmt.Fprintln(a.Writer, "Incorrect Usage.")
- fmt.Fprintln(a.Writer)
- ShowSubcommandHelp(context)
- return err
- }
-
- if len(a.Commands) > 0 {
- if checkSubcommandHelp(context) {
- return nil
- }
- } else {
- if checkCommandHelp(ctx, context.Args().First()) {
- return nil
- }
- }
-
- if a.After != nil {
- defer func() {
- afterErr := a.After(context)
- if afterErr != nil {
- if err != nil {
- err = NewMultiError(err, afterErr)
- } else {
- err = afterErr
- }
- }
- }()
- }
-
- if a.Before != nil {
- err := a.Before(context)
- if err != nil {
- return err
- }
- }
-
- args := context.Args()
- if args.Present() {
- name := args.First()
- c := a.Command(name)
- if c != nil {
- return c.Run(context)
- }
- }
-
- // Run default Action
- a.Action(context)
-
- return nil
-}
-
-// Returns the named command on App. Returns nil if the command does not exist
-func (a *App) Command(name string) *Command {
- for _, c := range a.Commands {
- if c.HasName(name) {
- return &c
- }
- }
-
- return nil
-}
-
-func (a *App) hasFlag(flag Flag) bool {
- for _, f := range a.Flags {
- if flag == f {
- return true
- }
- }
-
- return false
-}
-
-func (a *App) appendFlag(flag Flag) {
- if !a.hasFlag(flag) {
- a.Flags = append(a.Flags, flag)
- }
-}
-
-// Author represents someone who has contributed to a cli project.
-type Author struct {
- Name string // The Authors name
- Email string // The Authors email
-}
-
-// String makes Author comply to the Stringer interface, to allow an easy print in the templating process
-func (a Author) String() string {
- e := ""
- if a.Email != "" {
- e = "<" + a.Email + "> "
- }
-
- return fmt.Sprintf("%v %v", a.Name, e)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete
deleted file mode 100644
index 21a232f1..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete
+++ /dev/null
@@ -1,14 +0,0 @@
-#! /bin/bash
-
-: ${PROG:=$(basename ${BASH_SOURCE})}
-
-_cli_bash_autocomplete() {
- local cur opts base
- COMPREPLY=()
- cur="${COMP_WORDS[COMP_CWORD]}"
- opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion )
- COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
- return 0
- }
-
- complete -F _cli_bash_autocomplete $PROG
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/zsh_autocomplete b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/zsh_autocomplete
deleted file mode 100644
index 5430a18f..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/zsh_autocomplete
+++ /dev/null
@@ -1,5 +0,0 @@
-autoload -U compinit && compinit
-autoload -U bashcompinit && bashcompinit
-
-script_dir=$(dirname $0)
-source ${script_dir}/bash_autocomplete
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/cli.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/cli.go
deleted file mode 100644
index 31dc9124..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/cli.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Package cli provides a minimal framework for creating and organizing command line
-// Go applications. cli is designed to be easy to understand and write, the most simple
-// cli application can be written as follows:
-// func main() {
-// cli.NewApp().Run(os.Args)
-// }
-//
-// Of course this application does not do much, so let's make this an actual application:
-// func main() {
-// app := cli.NewApp()
-// app.Name = "greet"
-// app.Usage = "say a greeting"
-// app.Action = func(c *cli.Context) {
-// println("Greetings")
-// }
-//
-// app.Run(os.Args)
-// }
-package cli
-
-import (
- "strings"
-)
-
-type MultiError struct {
- Errors []error
-}
-
-func NewMultiError(err ...error) MultiError {
- return MultiError{Errors: err}
-}
-
-func (m MultiError) Error() string {
- errs := make([]string, len(m.Errors))
- for i, err := range m.Errors {
- errs[i] = err.Error()
- }
-
- return strings.Join(errs, "\n")
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/command.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/command.go
deleted file mode 100644
index 824e77ba..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/command.go
+++ /dev/null
@@ -1,216 +0,0 @@
-package cli
-
-import (
- "fmt"
- "io/ioutil"
- "strings"
-)
-
-// Command is a subcommand for a cli.App.
-type Command struct {
- // The name of the command
- Name string
- // short name of the command. Typically one character (deprecated, use `Aliases`)
- ShortName string
- // A list of aliases for the command
- Aliases []string
- // A short description of the usage of this command
- Usage string
- // A longer explanation of how the command works
- Description string
- // A short description of the arguments of this command
- ArgsUsage string
- // The function to call when checking for bash command completions
- BashComplete func(context *Context)
- // An action to execute before any sub-subcommands are run, but after the context is ready
- // If a non-nil error is returned, no sub-subcommands are run
- Before func(context *Context) error
- // An action to execute after any subcommands are run, but after the subcommand has finished
- // It is run even if Action() panics
- After func(context *Context) error
- // The function to call when this command is invoked
- Action func(context *Context)
- // List of child commands
- Subcommands []Command
- // List of flags to parse
- Flags []Flag
- // Treat all flags as normal arguments if true
- SkipFlagParsing bool
- // Boolean to hide built-in help command
- HideHelp bool
-
- // Full name of command for help, defaults to full command name, including parent commands.
- HelpName string
- commandNamePath []string
-}
-
-// Returns the full name of the command.
-// For subcommands this ensures that parent commands are part of the command path
-func (c Command) FullName() string {
- if c.commandNamePath == nil {
- return c.Name
- }
- return strings.Join(c.commandNamePath, " ")
-}
-
-// Invokes the command given the context, parses ctx.Args() to generate command-specific flags
-func (c Command) Run(ctx *Context) error {
- if len(c.Subcommands) > 0 || c.Before != nil || c.After != nil {
- return c.startApp(ctx)
- }
-
- if !c.HideHelp && (HelpFlag != BoolFlag{}) {
- // append help to flags
- c.Flags = append(
- c.Flags,
- HelpFlag,
- )
- }
-
- if ctx.App.EnableBashCompletion {
- c.Flags = append(c.Flags, BashCompletionFlag)
- }
-
- set := flagSet(c.Name, c.Flags)
- set.SetOutput(ioutil.Discard)
-
- var err error
- if !c.SkipFlagParsing {
- firstFlagIndex := -1
- terminatorIndex := -1
- for index, arg := range ctx.Args() {
- if arg == "--" {
- terminatorIndex = index
- break
- } else if strings.HasPrefix(arg, "-") && firstFlagIndex == -1 {
- firstFlagIndex = index
- }
- }
-
- if firstFlagIndex > -1 {
- args := ctx.Args()
- regularArgs := make([]string, len(args[1:firstFlagIndex]))
- copy(regularArgs, args[1:firstFlagIndex])
-
- var flagArgs []string
- if terminatorIndex > -1 {
- flagArgs = args[firstFlagIndex:terminatorIndex]
- regularArgs = append(regularArgs, args[terminatorIndex:]...)
- } else {
- flagArgs = args[firstFlagIndex:]
- }
-
- err = set.Parse(append(flagArgs, regularArgs...))
- } else {
- err = set.Parse(ctx.Args().Tail())
- }
- } else {
- if c.SkipFlagParsing {
- err = set.Parse(append([]string{"--"}, ctx.Args().Tail()...))
- }
- }
-
- if err != nil {
- fmt.Fprintln(ctx.App.Writer, "Incorrect Usage.")
- fmt.Fprintln(ctx.App.Writer)
- ShowCommandHelp(ctx, c.Name)
- return err
- }
-
- nerr := normalizeFlags(c.Flags, set)
- if nerr != nil {
- fmt.Fprintln(ctx.App.Writer, nerr)
- fmt.Fprintln(ctx.App.Writer)
- ShowCommandHelp(ctx, c.Name)
- return nerr
- }
- context := NewContext(ctx.App, set, ctx)
-
- if checkCommandCompletions(context, c.Name) {
- return nil
- }
-
- if checkCommandHelp(context, c.Name) {
- return nil
- }
- context.Command = c
- c.Action(context)
- return nil
-}
-
-func (c Command) Names() []string {
- names := []string{c.Name}
-
- if c.ShortName != "" {
- names = append(names, c.ShortName)
- }
-
- return append(names, c.Aliases...)
-}
-
-// Returns true if Command.Name or Command.ShortName matches given name
-func (c Command) HasName(name string) bool {
- for _, n := range c.Names() {
- if n == name {
- return true
- }
- }
- return false
-}
-
-func (c Command) startApp(ctx *Context) error {
- app := NewApp()
-
- // set the name and usage
- app.Name = fmt.Sprintf("%s %s", ctx.App.Name, c.Name)
- if c.HelpName == "" {
- app.HelpName = c.HelpName
- } else {
- app.HelpName = fmt.Sprintf("%s %s", ctx.App.Name, c.Name)
- }
-
- if c.Description != "" {
- app.Usage = c.Description
- } else {
- app.Usage = c.Usage
- }
-
- // set CommandNotFound
- app.CommandNotFound = ctx.App.CommandNotFound
-
- // set the flags and commands
- app.Commands = c.Subcommands
- app.Flags = c.Flags
- app.HideHelp = c.HideHelp
-
- app.Version = ctx.App.Version
- app.HideVersion = ctx.App.HideVersion
- app.Compiled = ctx.App.Compiled
- app.Author = ctx.App.Author
- app.Email = ctx.App.Email
- app.Writer = ctx.App.Writer
-
- // bash completion
- app.EnableBashCompletion = ctx.App.EnableBashCompletion
- if c.BashComplete != nil {
- app.BashComplete = c.BashComplete
- }
-
- // set the actions
- app.Before = c.Before
- app.After = c.After
- if c.Action != nil {
- app.Action = c.Action
- } else {
- app.Action = helpSubcommand.Action
- }
-
- var newCmds []Command
- for _, cc := range app.Commands {
- cc.commandNamePath = []string{c.Name, cc.Name}
- newCmds = append(newCmds, cc)
- }
- app.Commands = newCmds
-
- return app.RunAsSubcommand(ctx)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/context.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/context.go
deleted file mode 100644
index 0513d34f..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/context.go
+++ /dev/null
@@ -1,388 +0,0 @@
-package cli
-
-import (
- "errors"
- "flag"
- "strconv"
- "strings"
- "time"
-)
-
-// Context is a type that is passed through to
-// each Handler action in a cli application. Context
-// can be used to retrieve context-specific Args and
-// parsed command-line options.
-type Context struct {
- App *App
- Command Command
- flagSet *flag.FlagSet
- setFlags map[string]bool
- globalSetFlags map[string]bool
- parentContext *Context
-}
-
-// Creates a new context. For use in when invoking an App or Command action.
-func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
- return &Context{App: app, flagSet: set, parentContext: parentCtx}
-}
-
-// Looks up the value of a local int flag, returns 0 if no int flag exists
-func (c *Context) Int(name string) int {
- return lookupInt(name, c.flagSet)
-}
-
-// Looks up the value of a local time.Duration flag, returns 0 if no time.Duration flag exists
-func (c *Context) Duration(name string) time.Duration {
- return lookupDuration(name, c.flagSet)
-}
-
-// Looks up the value of a local float64 flag, returns 0 if no float64 flag exists
-func (c *Context) Float64(name string) float64 {
- return lookupFloat64(name, c.flagSet)
-}
-
-// Looks up the value of a local bool flag, returns false if no bool flag exists
-func (c *Context) Bool(name string) bool {
- return lookupBool(name, c.flagSet)
-}
-
-// Looks up the value of a local boolT flag, returns false if no bool flag exists
-func (c *Context) BoolT(name string) bool {
- return lookupBoolT(name, c.flagSet)
-}
-
-// Looks up the value of a local string flag, returns "" if no string flag exists
-func (c *Context) String(name string) string {
- return lookupString(name, c.flagSet)
-}
-
-// Looks up the value of a local string slice flag, returns nil if no string slice flag exists
-func (c *Context) StringSlice(name string) []string {
- return lookupStringSlice(name, c.flagSet)
-}
-
-// Looks up the value of a local int slice flag, returns nil if no int slice flag exists
-func (c *Context) IntSlice(name string) []int {
- return lookupIntSlice(name, c.flagSet)
-}
-
-// Looks up the value of a local generic flag, returns nil if no generic flag exists
-func (c *Context) Generic(name string) interface{} {
- return lookupGeneric(name, c.flagSet)
-}
-
-// Looks up the value of a global int flag, returns 0 if no int flag exists
-func (c *Context) GlobalInt(name string) int {
- if fs := lookupGlobalFlagSet(name, c); fs != nil {
- return lookupInt(name, fs)
- }
- return 0
-}
-
-// Looks up the value of a global time.Duration flag, returns 0 if no time.Duration flag exists
-func (c *Context) GlobalDuration(name string) time.Duration {
- if fs := lookupGlobalFlagSet(name, c); fs != nil {
- return lookupDuration(name, fs)
- }
- return 0
-}
-
-// Looks up the value of a global bool flag, returns false if no bool flag exists
-func (c *Context) GlobalBool(name string) bool {
- if fs := lookupGlobalFlagSet(name, c); fs != nil {
- return lookupBool(name, fs)
- }
- return false
-}
-
-// Looks up the value of a global string flag, returns "" if no string flag exists
-func (c *Context) GlobalString(name string) string {
- if fs := lookupGlobalFlagSet(name, c); fs != nil {
- return lookupString(name, fs)
- }
- return ""
-}
-
-// Looks up the value of a global string slice flag, returns nil if no string slice flag exists
-func (c *Context) GlobalStringSlice(name string) []string {
- if fs := lookupGlobalFlagSet(name, c); fs != nil {
- return lookupStringSlice(name, fs)
- }
- return nil
-}
-
-// Looks up the value of a global int slice flag, returns nil if no int slice flag exists
-func (c *Context) GlobalIntSlice(name string) []int {
- if fs := lookupGlobalFlagSet(name, c); fs != nil {
- return lookupIntSlice(name, fs)
- }
- return nil
-}
-
-// Looks up the value of a global generic flag, returns nil if no generic flag exists
-func (c *Context) GlobalGeneric(name string) interface{} {
- if fs := lookupGlobalFlagSet(name, c); fs != nil {
- return lookupGeneric(name, fs)
- }
- return nil
-}
-
-// Returns the number of flags set
-func (c *Context) NumFlags() int {
- return c.flagSet.NFlag()
-}
-
-// Determines if the flag was actually set
-func (c *Context) IsSet(name string) bool {
- if c.setFlags == nil {
- c.setFlags = make(map[string]bool)
- c.flagSet.Visit(func(f *flag.Flag) {
- c.setFlags[f.Name] = true
- })
- }
- return c.setFlags[name] == true
-}
-
-// Determines if the global flag was actually set
-func (c *Context) GlobalIsSet(name string) bool {
- if c.globalSetFlags == nil {
- c.globalSetFlags = make(map[string]bool)
- ctx := c
- if ctx.parentContext != nil {
- ctx = ctx.parentContext
- }
- for ; ctx != nil && c.globalSetFlags[name] == false; ctx = ctx.parentContext {
- ctx.flagSet.Visit(func(f *flag.Flag) {
- c.globalSetFlags[f.Name] = true
- })
- }
- }
- return c.globalSetFlags[name]
-}
-
-// Returns a slice of flag names used in this context.
-func (c *Context) FlagNames() (names []string) {
- for _, flag := range c.Command.Flags {
- name := strings.Split(flag.GetName(), ",")[0]
- if name == "help" {
- continue
- }
- names = append(names, name)
- }
- return
-}
-
-// Returns a slice of global flag names used by the app.
-func (c *Context) GlobalFlagNames() (names []string) {
- for _, flag := range c.App.Flags {
- name := strings.Split(flag.GetName(), ",")[0]
- if name == "help" || name == "version" {
- continue
- }
- names = append(names, name)
- }
- return
-}
-
-// Returns the parent context, if any
-func (c *Context) Parent() *Context {
- return c.parentContext
-}
-
-type Args []string
-
-// Returns the command line arguments associated with the context.
-func (c *Context) Args() Args {
- args := Args(c.flagSet.Args())
- return args
-}
-
-// Returns the nth argument, or else a blank string
-func (a Args) Get(n int) string {
- if len(a) > n {
- return a[n]
- }
- return ""
-}
-
-// Returns the first argument, or else a blank string
-func (a Args) First() string {
- return a.Get(0)
-}
-
-// Return the rest of the arguments (not the first one)
-// or else an empty string slice
-func (a Args) Tail() []string {
- if len(a) >= 2 {
- return []string(a)[1:]
- }
- return []string{}
-}
-
-// Checks if there are any arguments present
-func (a Args) Present() bool {
- return len(a) != 0
-}
-
-// Swaps arguments at the given indexes
-func (a Args) Swap(from, to int) error {
- if from >= len(a) || to >= len(a) {
- return errors.New("index out of range")
- }
- a[from], a[to] = a[to], a[from]
- return nil
-}
-
-func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet {
- if ctx.parentContext != nil {
- ctx = ctx.parentContext
- }
- for ; ctx != nil; ctx = ctx.parentContext {
- if f := ctx.flagSet.Lookup(name); f != nil {
- return ctx.flagSet
- }
- }
- return nil
-}
-
-func lookupInt(name string, set *flag.FlagSet) int {
- f := set.Lookup(name)
- if f != nil {
- val, err := strconv.Atoi(f.Value.String())
- if err != nil {
- return 0
- }
- return val
- }
-
- return 0
-}
-
-func lookupDuration(name string, set *flag.FlagSet) time.Duration {
- f := set.Lookup(name)
- if f != nil {
- val, err := time.ParseDuration(f.Value.String())
- if err == nil {
- return val
- }
- }
-
- return 0
-}
-
-func lookupFloat64(name string, set *flag.FlagSet) float64 {
- f := set.Lookup(name)
- if f != nil {
- val, err := strconv.ParseFloat(f.Value.String(), 64)
- if err != nil {
- return 0
- }
- return val
- }
-
- return 0
-}
-
-func lookupString(name string, set *flag.FlagSet) string {
- f := set.Lookup(name)
- if f != nil {
- return f.Value.String()
- }
-
- return ""
-}
-
-func lookupStringSlice(name string, set *flag.FlagSet) []string {
- f := set.Lookup(name)
- if f != nil {
- return (f.Value.(*StringSlice)).Value()
-
- }
-
- return nil
-}
-
-func lookupIntSlice(name string, set *flag.FlagSet) []int {
- f := set.Lookup(name)
- if f != nil {
- return (f.Value.(*IntSlice)).Value()
-
- }
-
- return nil
-}
-
-func lookupGeneric(name string, set *flag.FlagSet) interface{} {
- f := set.Lookup(name)
- if f != nil {
- return f.Value
- }
- return nil
-}
-
-func lookupBool(name string, set *flag.FlagSet) bool {
- f := set.Lookup(name)
- if f != nil {
- val, err := strconv.ParseBool(f.Value.String())
- if err != nil {
- return false
- }
- return val
- }
-
- return false
-}
-
-func lookupBoolT(name string, set *flag.FlagSet) bool {
- f := set.Lookup(name)
- if f != nil {
- val, err := strconv.ParseBool(f.Value.String())
- if err != nil {
- return true
- }
- return val
- }
-
- return false
-}
-
-func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
- switch ff.Value.(type) {
- case *StringSlice:
- default:
- set.Set(name, ff.Value.String())
- }
-}
-
-func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
- visited := make(map[string]bool)
- set.Visit(func(f *flag.Flag) {
- visited[f.Name] = true
- })
- for _, f := range flags {
- parts := strings.Split(f.GetName(), ",")
- if len(parts) == 1 {
- continue
- }
- var ff *flag.Flag
- for _, name := range parts {
- name = strings.Trim(name, " ")
- if visited[name] {
- if ff != nil {
- return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name)
- }
- ff = set.Lookup(name)
- }
- }
- if ff == nil {
- continue
- }
- for _, name := range parts {
- name = strings.Trim(name, " ")
- if !visited[name] {
- copyFlag(name, ff, set)
- }
- }
- }
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/flag.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/flag.go
deleted file mode 100644
index 49f30994..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/flag.go
+++ /dev/null
@@ -1,527 +0,0 @@
-package cli
-
-import (
- "flag"
- "fmt"
- "os"
- "strconv"
- "strings"
- "time"
-)
-
-// This flag enables bash-completion for all commands and subcommands
-var BashCompletionFlag = BoolFlag{
- Name: "generate-bash-completion",
-}
-
-// This flag prints the version for the application
-var VersionFlag = BoolFlag{
- Name: "version, v",
- Usage: "print the version",
-}
-
-// This flag prints the help for all commands and subcommands
-// Set to the zero value (BoolFlag{}) to disable flag -- keeps subcommand
-// unless HideHelp is set to true)
-var HelpFlag = BoolFlag{
- Name: "help, h",
- Usage: "show help",
-}
-
-// Flag is a common interface related to parsing flags in cli.
-// For more advanced flag parsing techniques, it is recomended that
-// this interface be implemented.
-type Flag interface {
- fmt.Stringer
- // Apply Flag settings to the given flag set
- Apply(*flag.FlagSet)
- GetName() string
-}
-
-func flagSet(name string, flags []Flag) *flag.FlagSet {
- set := flag.NewFlagSet(name, flag.ContinueOnError)
-
- for _, f := range flags {
- f.Apply(set)
- }
- return set
-}
-
-func eachName(longName string, fn func(string)) {
- parts := strings.Split(longName, ",")
- for _, name := range parts {
- name = strings.Trim(name, " ")
- fn(name)
- }
-}
-
-// Generic is a generic parseable type identified by a specific flag
-type Generic interface {
- Set(value string) error
- String() string
-}
-
-// GenericFlag is the flag type for types implementing Generic
-type GenericFlag struct {
- Name string
- Value Generic
- Usage string
- EnvVar string
-}
-
-// String returns the string representation of the generic flag to display the
-// help text to the user (uses the String() method of the generic flag to show
-// the value)
-func (f GenericFlag) String() string {
- return withEnvHint(f.EnvVar, fmt.Sprintf("%s%s \"%v\"\t%v", prefixFor(f.Name), f.Name, f.Value, f.Usage))
-}
-
-// Apply takes the flagset and calls Set on the generic flag with the value
-// provided by the user for parsing by the flag
-func (f GenericFlag) Apply(set *flag.FlagSet) {
- val := f.Value
- if f.EnvVar != "" {
- for _, envVar := range strings.Split(f.EnvVar, ",") {
- envVar = strings.TrimSpace(envVar)
- if envVal := os.Getenv(envVar); envVal != "" {
- val.Set(envVal)
- break
- }
- }
- }
-
- eachName(f.Name, func(name string) {
- set.Var(f.Value, name, f.Usage)
- })
-}
-
-func (f GenericFlag) GetName() string {
- return f.Name
-}
-
-// StringSlice is an opaque type for []string to satisfy flag.Value
-type StringSlice []string
-
-// Set appends the string value to the list of values
-func (f *StringSlice) Set(value string) error {
- *f = append(*f, value)
- return nil
-}
-
-// String returns a readable representation of this value (for usage defaults)
-func (f *StringSlice) String() string {
- return fmt.Sprintf("%s", *f)
-}
-
-// Value returns the slice of strings set by this flag
-func (f *StringSlice) Value() []string {
- return *f
-}
-
-// StringSlice is a string flag that can be specified multiple times on the
-// command-line
-type StringSliceFlag struct {
- Name string
- Value *StringSlice
- Usage string
- EnvVar string
-}
-
-// String returns the usage
-func (f StringSliceFlag) String() string {
- firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
- pref := prefixFor(firstName)
- return withEnvHint(f.EnvVar, fmt.Sprintf("%s [%v]\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage))
-}
-
-// Apply populates the flag given the flag set and environment
-func (f StringSliceFlag) Apply(set *flag.FlagSet) {
- if f.EnvVar != "" {
- for _, envVar := range strings.Split(f.EnvVar, ",") {
- envVar = strings.TrimSpace(envVar)
- if envVal := os.Getenv(envVar); envVal != "" {
- newVal := &StringSlice{}
- for _, s := range strings.Split(envVal, ",") {
- s = strings.TrimSpace(s)
- newVal.Set(s)
- }
- f.Value = newVal
- break
- }
- }
- }
-
- eachName(f.Name, func(name string) {
- if f.Value == nil {
- f.Value = &StringSlice{}
- }
- set.Var(f.Value, name, f.Usage)
- })
-}
-
-func (f StringSliceFlag) GetName() string {
- return f.Name
-}
-
-// StringSlice is an opaque type for []int to satisfy flag.Value
-type IntSlice []int
-
-// Set parses the value into an integer and appends it to the list of values
-func (f *IntSlice) Set(value string) error {
- tmp, err := strconv.Atoi(value)
- if err != nil {
- return err
- } else {
- *f = append(*f, tmp)
- }
- return nil
-}
-
-// String returns a readable representation of this value (for usage defaults)
-func (f *IntSlice) String() string {
- return fmt.Sprintf("%d", *f)
-}
-
-// Value returns the slice of ints set by this flag
-func (f *IntSlice) Value() []int {
- return *f
-}
-
-// IntSliceFlag is an int flag that can be specified multiple times on the
-// command-line
-type IntSliceFlag struct {
- Name string
- Value *IntSlice
- Usage string
- EnvVar string
-}
-
-// String returns the usage
-func (f IntSliceFlag) String() string {
- firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
- pref := prefixFor(firstName)
- return withEnvHint(f.EnvVar, fmt.Sprintf("%s [%v]\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage))
-}
-
-// Apply populates the flag given the flag set and environment
-func (f IntSliceFlag) Apply(set *flag.FlagSet) {
- if f.EnvVar != "" {
- for _, envVar := range strings.Split(f.EnvVar, ",") {
- envVar = strings.TrimSpace(envVar)
- if envVal := os.Getenv(envVar); envVal != "" {
- newVal := &IntSlice{}
- for _, s := range strings.Split(envVal, ",") {
- s = strings.TrimSpace(s)
- err := newVal.Set(s)
- if err != nil {
- fmt.Fprintf(os.Stderr, err.Error())
- }
- }
- f.Value = newVal
- break
- }
- }
- }
-
- eachName(f.Name, func(name string) {
- if f.Value == nil {
- f.Value = &IntSlice{}
- }
- set.Var(f.Value, name, f.Usage)
- })
-}
-
-func (f IntSliceFlag) GetName() string {
- return f.Name
-}
-
-// BoolFlag is a switch that defaults to false
-type BoolFlag struct {
- Name string
- Usage string
- EnvVar string
- Destination *bool
-}
-
-// String returns a readable representation of this value (for usage defaults)
-func (f BoolFlag) String() string {
- return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage))
-}
-
-// Apply populates the flag given the flag set and environment
-func (f BoolFlag) Apply(set *flag.FlagSet) {
- val := false
- if f.EnvVar != "" {
- for _, envVar := range strings.Split(f.EnvVar, ",") {
- envVar = strings.TrimSpace(envVar)
- if envVal := os.Getenv(envVar); envVal != "" {
- envValBool, err := strconv.ParseBool(envVal)
- if err == nil {
- val = envValBool
- }
- break
- }
- }
- }
-
- eachName(f.Name, func(name string) {
- if f.Destination != nil {
- set.BoolVar(f.Destination, name, val, f.Usage)
- return
- }
- set.Bool(name, val, f.Usage)
- })
-}
-
-func (f BoolFlag) GetName() string {
- return f.Name
-}
-
-// BoolTFlag this represents a boolean flag that is true by default, but can
-// still be set to false by --some-flag=false
-type BoolTFlag struct {
- Name string
- Usage string
- EnvVar string
- Destination *bool
-}
-
-// String returns a readable representation of this value (for usage defaults)
-func (f BoolTFlag) String() string {
- return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage))
-}
-
-// Apply populates the flag given the flag set and environment
-func (f BoolTFlag) Apply(set *flag.FlagSet) {
- val := true
- if f.EnvVar != "" {
- for _, envVar := range strings.Split(f.EnvVar, ",") {
- envVar = strings.TrimSpace(envVar)
- if envVal := os.Getenv(envVar); envVal != "" {
- envValBool, err := strconv.ParseBool(envVal)
- if err == nil {
- val = envValBool
- break
- }
- }
- }
- }
-
- eachName(f.Name, func(name string) {
- if f.Destination != nil {
- set.BoolVar(f.Destination, name, val, f.Usage)
- return
- }
- set.Bool(name, val, f.Usage)
- })
-}
-
-func (f BoolTFlag) GetName() string {
- return f.Name
-}
-
-// StringFlag represents a flag that takes as string value
-type StringFlag struct {
- Name string
- Value string
- Usage string
- EnvVar string
- Destination *string
-}
-
-// String returns the usage
-func (f StringFlag) String() string {
- var fmtString string
- fmtString = "%s %v\t%v"
-
- if len(f.Value) > 0 {
- fmtString = "%s \"%v\"\t%v"
- } else {
- fmtString = "%s %v\t%v"
- }
-
- return withEnvHint(f.EnvVar, fmt.Sprintf(fmtString, prefixedNames(f.Name), f.Value, f.Usage))
-}
-
-// Apply populates the flag given the flag set and environment
-func (f StringFlag) Apply(set *flag.FlagSet) {
- if f.EnvVar != "" {
- for _, envVar := range strings.Split(f.EnvVar, ",") {
- envVar = strings.TrimSpace(envVar)
- if envVal := os.Getenv(envVar); envVal != "" {
- f.Value = envVal
- break
- }
- }
- }
-
- eachName(f.Name, func(name string) {
- if f.Destination != nil {
- set.StringVar(f.Destination, name, f.Value, f.Usage)
- return
- }
- set.String(name, f.Value, f.Usage)
- })
-}
-
-func (f StringFlag) GetName() string {
- return f.Name
-}
-
-// IntFlag is a flag that takes an integer
-// Errors if the value provided cannot be parsed
-type IntFlag struct {
- Name string
- Value int
- Usage string
- EnvVar string
- Destination *int
-}
-
-// String returns the usage
-func (f IntFlag) String() string {
- return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage))
-}
-
-// Apply populates the flag given the flag set and environment
-func (f IntFlag) Apply(set *flag.FlagSet) {
- if f.EnvVar != "" {
- for _, envVar := range strings.Split(f.EnvVar, ",") {
- envVar = strings.TrimSpace(envVar)
- if envVal := os.Getenv(envVar); envVal != "" {
- envValInt, err := strconv.ParseInt(envVal, 0, 64)
- if err == nil {
- f.Value = int(envValInt)
- break
- }
- }
- }
- }
-
- eachName(f.Name, func(name string) {
- if f.Destination != nil {
- set.IntVar(f.Destination, name, f.Value, f.Usage)
- return
- }
- set.Int(name, f.Value, f.Usage)
- })
-}
-
-func (f IntFlag) GetName() string {
- return f.Name
-}
-
-// DurationFlag is a flag that takes a duration specified in Go's duration
-// format: https://golang.org/pkg/time/#ParseDuration
-type DurationFlag struct {
- Name string
- Value time.Duration
- Usage string
- EnvVar string
- Destination *time.Duration
-}
-
-// String returns a readable representation of this value (for usage defaults)
-func (f DurationFlag) String() string {
- return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage))
-}
-
-// Apply populates the flag given the flag set and environment
-func (f DurationFlag) Apply(set *flag.FlagSet) {
- if f.EnvVar != "" {
- for _, envVar := range strings.Split(f.EnvVar, ",") {
- envVar = strings.TrimSpace(envVar)
- if envVal := os.Getenv(envVar); envVal != "" {
- envValDuration, err := time.ParseDuration(envVal)
- if err == nil {
- f.Value = envValDuration
- break
- }
- }
- }
- }
-
- eachName(f.Name, func(name string) {
- if f.Destination != nil {
- set.DurationVar(f.Destination, name, f.Value, f.Usage)
- return
- }
- set.Duration(name, f.Value, f.Usage)
- })
-}
-
-func (f DurationFlag) GetName() string {
- return f.Name
-}
-
-// Float64Flag is a flag that takes an float value
-// Errors if the value provided cannot be parsed
-type Float64Flag struct {
- Name string
- Value float64
- Usage string
- EnvVar string
- Destination *float64
-}
-
-// String returns the usage
-func (f Float64Flag) String() string {
- return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage))
-}
-
-// Apply populates the flag given the flag set and environment
-func (f Float64Flag) Apply(set *flag.FlagSet) {
- if f.EnvVar != "" {
- for _, envVar := range strings.Split(f.EnvVar, ",") {
- envVar = strings.TrimSpace(envVar)
- if envVal := os.Getenv(envVar); envVal != "" {
- envValFloat, err := strconv.ParseFloat(envVal, 10)
- if err == nil {
- f.Value = float64(envValFloat)
- }
- }
- }
- }
-
- eachName(f.Name, func(name string) {
- if f.Destination != nil {
- set.Float64Var(f.Destination, name, f.Value, f.Usage)
- return
- }
- set.Float64(name, f.Value, f.Usage)
- })
-}
-
-func (f Float64Flag) GetName() string {
- return f.Name
-}
-
-func prefixFor(name string) (prefix string) {
- if len(name) == 1 {
- prefix = "-"
- } else {
- prefix = "--"
- }
-
- return
-}
-
-func prefixedNames(fullName string) (prefixed string) {
- parts := strings.Split(fullName, ",")
- for i, name := range parts {
- name = strings.Trim(name, " ")
- prefixed += prefixFor(name) + name
- if i < len(parts)-1 {
- prefixed += ", "
- }
- }
- return
-}
-
-func withEnvHint(envVar, str string) string {
- envText := ""
- if envVar != "" {
- envText = fmt.Sprintf(" [$%s]", strings.Join(strings.Split(envVar, ","), ", $"))
- }
- return str + envText
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/help.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/help.go
deleted file mode 100644
index a246f63a..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/codegangsta/cli/help.go
+++ /dev/null
@@ -1,246 +0,0 @@
-package cli
-
-import (
- "fmt"
- "io"
- "strings"
- "text/tabwriter"
- "text/template"
-)
-
-// The text template for the Default help topic.
-// cli.go uses text/template to render templates. You can
-// render custom help text by setting this variable.
-var AppHelpTemplate = `NAME:
- {{.Name}} - {{.Usage}}
-
-USAGE:
- {{.HelpName}} {{if .Flags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}
- {{if .Version}}
-VERSION:
- {{.Version}}
- {{end}}{{if len .Authors}}
-AUTHOR(S):
- {{range .Authors}}{{ . }}{{end}}
- {{end}}{{if .Commands}}
-COMMANDS:
- {{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
- {{end}}{{end}}{{if .Flags}}
-GLOBAL OPTIONS:
- {{range .Flags}}{{.}}
- {{end}}{{end}}{{if .Copyright }}
-COPYRIGHT:
- {{.Copyright}}
- {{end}}
-`
-
-// The text template for the command help topic.
-// cli.go uses text/template to render templates. You can
-// render custom help text by setting this variable.
-var CommandHelpTemplate = `NAME:
- {{.HelpName}} - {{.Usage}}
-
-USAGE:
- {{.HelpName}}{{if .Flags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{if .Description}}
-
-DESCRIPTION:
- {{.Description}}{{end}}{{if .Flags}}
-
-OPTIONS:
- {{range .Flags}}{{.}}
- {{end}}{{ end }}
-`
-
-// The text template for the subcommand help topic.
-// cli.go uses text/template to render templates. You can
-// render custom help text by setting this variable.
-var SubcommandHelpTemplate = `NAME:
- {{.HelpName}} - {{.Usage}}
-
-USAGE:
- {{.HelpName}} command{{if .Flags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}
-
-COMMANDS:
- {{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
- {{end}}{{if .Flags}}
-OPTIONS:
- {{range .Flags}}{{.}}
- {{end}}{{end}}
-`
-
-var helpCommand = Command{
- Name: "help",
- Aliases: []string{"h"},
- Usage: "Shows a list of commands or help for one command",
- ArgsUsage: "[command]",
- Action: func(c *Context) {
- args := c.Args()
- if args.Present() {
- ShowCommandHelp(c, args.First())
- } else {
- ShowAppHelp(c)
- }
- },
-}
-
-var helpSubcommand = Command{
- Name: "help",
- Aliases: []string{"h"},
- Usage: "Shows a list of commands or help for one command",
- ArgsUsage: "[command]",
- Action: func(c *Context) {
- args := c.Args()
- if args.Present() {
- ShowCommandHelp(c, args.First())
- } else {
- ShowSubcommandHelp(c)
- }
- },
-}
-
-// Prints help for the App or Command
-type helpPrinter func(w io.Writer, templ string, data interface{})
-
-var HelpPrinter helpPrinter = printHelp
-
-// Prints version for the App
-var VersionPrinter = printVersion
-
-func ShowAppHelp(c *Context) {
- HelpPrinter(c.App.Writer, AppHelpTemplate, c.App)
-}
-
-// Prints the list of subcommands as the default app completion method
-func DefaultAppComplete(c *Context) {
- for _, command := range c.App.Commands {
- for _, name := range command.Names() {
- fmt.Fprintln(c.App.Writer, name)
- }
- }
-}
-
-// Prints help for the given command
-func ShowCommandHelp(ctx *Context, command string) {
- // show the subcommand help for a command with subcommands
- if command == "" {
- HelpPrinter(ctx.App.Writer, SubcommandHelpTemplate, ctx.App)
- return
- }
-
- for _, c := range ctx.App.Commands {
- if c.HasName(command) {
- HelpPrinter(ctx.App.Writer, CommandHelpTemplate, c)
- return
- }
- }
-
- if ctx.App.CommandNotFound != nil {
- ctx.App.CommandNotFound(ctx, command)
- } else {
- fmt.Fprintf(ctx.App.Writer, "No help topic for '%v'\n", command)
- }
-}
-
-// Prints help for the given subcommand
-func ShowSubcommandHelp(c *Context) {
- ShowCommandHelp(c, c.Command.Name)
-}
-
-// Prints the version number of the App
-func ShowVersion(c *Context) {
- VersionPrinter(c)
-}
-
-func printVersion(c *Context) {
- fmt.Fprintf(c.App.Writer, "%v version %v\n", c.App.Name, c.App.Version)
-}
-
-// Prints the lists of commands within a given context
-func ShowCompletions(c *Context) {
- a := c.App
- if a != nil && a.BashComplete != nil {
- a.BashComplete(c)
- }
-}
-
-// Prints the custom completions for a given command
-func ShowCommandCompletions(ctx *Context, command string) {
- c := ctx.App.Command(command)
- if c != nil && c.BashComplete != nil {
- c.BashComplete(ctx)
- }
-}
-
-func printHelp(out io.Writer, templ string, data interface{}) {
- funcMap := template.FuncMap{
- "join": strings.Join,
- }
-
- w := tabwriter.NewWriter(out, 0, 8, 1, '\t', 0)
- t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
- err := t.Execute(w, data)
- if err != nil {
- panic(err)
- }
- w.Flush()
-}
-
-func checkVersion(c *Context) bool {
- found := false
- if VersionFlag.Name != "" {
- eachName(VersionFlag.Name, func(name string) {
- if c.GlobalBool(name) || c.Bool(name) {
- found = true
- }
- })
- }
- return found
-}
-
-func checkHelp(c *Context) bool {
- found := false
- if HelpFlag.Name != "" {
- eachName(HelpFlag.Name, func(name string) {
- if c.GlobalBool(name) || c.Bool(name) {
- found = true
- }
- })
- }
- return found
-}
-
-func checkCommandHelp(c *Context, name string) bool {
- if c.Bool("h") || c.Bool("help") {
- ShowCommandHelp(c, name)
- return true
- }
-
- return false
-}
-
-func checkSubcommandHelp(c *Context) bool {
- if c.GlobalBool("h") || c.GlobalBool("help") {
- ShowSubcommandHelp(c)
- return true
- }
-
- return false
-}
-
-func checkCompletions(c *Context) bool {
- if (c.GlobalBool(BashCompletionFlag.Name) || c.Bool(BashCompletionFlag.Name)) && c.App.EnableBashCompletion {
- ShowCompletions(c)
- return true
- }
-
- return false
-}
-
-func checkCommandCompletions(c *Context, name string) bool {
- if c.Bool(BashCompletionFlag.Name) && c.App.EnableBashCompletion {
- ShowCommandCompletions(c, name)
- return true
- }
-
- return false
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/LICENSE b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/LICENSE
deleted file mode 100644
index 37ec93a1..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/LICENSE
+++ /dev/null
@@ -1,191 +0,0 @@
-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:
-
-You must give any other recipients of the Work or Derivative Works a copy of
-this License; and
-You must cause any modified files to carry prominent notices stating that You
-changed the files; and
-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
-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/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/activation/files.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/activation/files.go
deleted file mode 100644
index c8e85fcd..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/activation/files.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// 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 activation implements primitives for systemd socket activation.
-package activation
-
-import (
- "os"
- "strconv"
- "syscall"
-)
-
-// based on: https://gist.github.com/alberts/4640792
-const (
- listenFdsStart = 3
-)
-
-func Files(unsetEnv bool) []*os.File {
- if unsetEnv {
- defer os.Unsetenv("LISTEN_PID")
- defer os.Unsetenv("LISTEN_FDS")
- }
-
- pid, err := strconv.Atoi(os.Getenv("LISTEN_PID"))
- if err != nil || pid != os.Getpid() {
- return nil
- }
-
- nfds, err := strconv.Atoi(os.Getenv("LISTEN_FDS"))
- if err != nil || nfds == 0 {
- return nil
- }
-
- files := make([]*os.File, 0, nfds)
- for fd := listenFdsStart; fd < listenFdsStart+nfds; fd++ {
- syscall.CloseOnExec(fd)
- files = append(files, os.NewFile(uintptr(fd), "LISTEN_FD_"+strconv.Itoa(fd)))
- }
-
- return files
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/activation/listeners.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/activation/listeners.go
deleted file mode 100644
index df27c29e..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/activation/listeners.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// 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 activation
-
-import (
- "crypto/tls"
- "net"
-)
-
-// Listeners returns a slice containing a net.Listener for each matching socket type
-// passed to this process.
-//
-// The order of the file descriptors is preserved in the returned slice.
-// Nil values are used to fill any gaps. For example if systemd were to return file descriptors
-// corresponding with "udp, tcp, tcp", then the slice would contain {nil, net.Listener, net.Listener}
-func Listeners(unsetEnv bool) ([]net.Listener, error) {
- files := Files(unsetEnv)
- listeners := make([]net.Listener, len(files))
-
- for i, f := range files {
- if pc, err := net.FileListener(f); err == nil {
- listeners[i] = pc
- }
- }
- return listeners, nil
-}
-
-// TLSListeners returns a slice containing a net.listener for each matching TCP socket type
-// passed to this process.
-// It uses default Listeners func and forces TCP sockets handlers to use TLS based on tlsConfig.
-func TLSListeners(unsetEnv bool, tlsConfig *tls.Config) ([]net.Listener, error) {
- listeners, err := Listeners(unsetEnv)
-
- if listeners == nil || err != nil {
- return nil, err
- }
-
- if tlsConfig != nil && err == nil {
- tlsConfig.NextProtos = []string{"http/1.1"}
-
- for i, l := range listeners {
- // Activate TLS only for TCP sockets
- if l.Addr().Network() == "tcp" {
- listeners[i] = tls.NewListener(l, tlsConfig)
- }
- }
- }
-
- return listeners, err
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/activation/packetconns.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/activation/packetconns.go
deleted file mode 100644
index 48b2ca02..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/activation/packetconns.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// 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 activation
-
-import (
- "net"
-)
-
-// PacketConns returns a slice containing a net.PacketConn for each matching socket type
-// passed to this process.
-//
-// The order of the file descriptors is preserved in the returned slice.
-// Nil values are used to fill any gaps. For example if systemd were to return file descriptors
-// corresponding with "udp, tcp, udp", then the slice would contain {net.PacketConn, nil, net.PacketConn}
-func PacketConns(unsetEnv bool) ([]net.PacketConn, error) {
- files := Files(unsetEnv)
- conns := make([]net.PacketConn, len(files))
-
- for i, f := range files {
- if pc, err := net.FilePacketConn(f); err == nil {
- conns[i] = pc
- }
- }
- return conns, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/dbus.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/dbus.go
deleted file mode 100644
index 5dd748e6..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/dbus.go
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// 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.
-
-// Integration with the systemd D-Bus API. See http://www.freedesktop.org/wiki/Software/systemd/dbus/
-package dbus
-
-import (
- "fmt"
- "os"
- "strconv"
- "strings"
- "sync"
-
- "github.com/godbus/dbus"
-)
-
-const (
- alpha = `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`
- num = `0123456789`
- alphanum = alpha + num
- signalBuffer = 100
-)
-
-// needsEscape checks whether a byte in a potential dbus ObjectPath needs to be escaped
-func needsEscape(i int, b byte) bool {
- // Escape everything that is not a-z-A-Z-0-9
- // Also escape 0-9 if it's the first character
- return strings.IndexByte(alphanum, b) == -1 ||
- (i == 0 && strings.IndexByte(num, b) != -1)
-}
-
-// PathBusEscape sanitizes a constituent string of a dbus ObjectPath using the
-// rules that systemd uses for serializing special characters.
-func PathBusEscape(path string) string {
- // Special case the empty string
- if len(path) == 0 {
- return "_"
- }
- n := []byte{}
- for i := 0; i < len(path); i++ {
- c := path[i]
- if needsEscape(i, c) {
- e := fmt.Sprintf("_%x", c)
- n = append(n, []byte(e)...)
- } else {
- n = append(n, c)
- }
- }
- return string(n)
-}
-
-// Conn is a connection to systemd's dbus endpoint.
-type Conn struct {
- // sysconn/sysobj are only used to call dbus methods
- sysconn *dbus.Conn
- sysobj dbus.BusObject
-
- // sigconn/sigobj are only used to receive dbus signals
- sigconn *dbus.Conn
- sigobj dbus.BusObject
-
- jobListener struct {
- jobs map[dbus.ObjectPath]chan<- string
- sync.Mutex
- }
- subscriber struct {
- updateCh chan<- *SubStateUpdate
- errCh chan<- error
- sync.Mutex
- ignore map[dbus.ObjectPath]int64
- cleanIgnore int64
- }
-}
-
-// New establishes a connection to the system bus and authenticates.
-// Callers should call Close() when done with the connection.
-func New() (*Conn, error) {
- return newConnection(func() (*dbus.Conn, error) {
- return dbusAuthHelloConnection(dbus.SystemBusPrivate)
- })
-}
-
-// NewUserConnection establishes a connection to the session bus and
-// authenticates. This can be used to connect to systemd user instances.
-// Callers should call Close() when done with the connection.
-func NewUserConnection() (*Conn, error) {
- return newConnection(func() (*dbus.Conn, error) {
- return dbusAuthHelloConnection(dbus.SessionBusPrivate)
- })
-}
-
-// NewSystemdConnection establishes a private, direct connection to systemd.
-// This can be used for communicating with systemd without a dbus daemon.
-// Callers should call Close() when done with the connection.
-func NewSystemdConnection() (*Conn, error) {
- return newConnection(func() (*dbus.Conn, error) {
- // We skip Hello when talking directly to systemd.
- return dbusAuthConnection(func() (*dbus.Conn, error) {
- return dbus.Dial("unix:path=/run/systemd/private")
- })
- })
-}
-
-// Close closes an established connection
-func (c *Conn) Close() {
- c.sysconn.Close()
- c.sigconn.Close()
-}
-
-func newConnection(createBus func() (*dbus.Conn, error)) (*Conn, error) {
- sysconn, err := createBus()
- if err != nil {
- return nil, err
- }
-
- sigconn, err := createBus()
- if err != nil {
- sysconn.Close()
- return nil, err
- }
-
- c := &Conn{
- sysconn: sysconn,
- sysobj: systemdObject(sysconn),
- sigconn: sigconn,
- sigobj: systemdObject(sigconn),
- }
-
- c.subscriber.ignore = make(map[dbus.ObjectPath]int64)
- c.jobListener.jobs = make(map[dbus.ObjectPath]chan<- string)
-
- // Setup the listeners on jobs so that we can get completions
- c.sigconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0,
- "type='signal', interface='org.freedesktop.systemd1.Manager', member='JobRemoved'")
-
- c.dispatch()
- return c, nil
-}
-
-func dbusAuthConnection(createBus func() (*dbus.Conn, error)) (*dbus.Conn, error) {
- conn, err := createBus()
- if err != nil {
- return nil, err
- }
-
- // Only use EXTERNAL method, and hardcode the uid (not username)
- // to avoid a username lookup (which requires a dynamically linked
- // libc)
- methods := []dbus.Auth{dbus.AuthExternal(strconv.Itoa(os.Getuid()))}
-
- err = conn.Auth(methods)
- if err != nil {
- conn.Close()
- return nil, err
- }
-
- return conn, nil
-}
-
-func dbusAuthHelloConnection(createBus func() (*dbus.Conn, error)) (*dbus.Conn, error) {
- conn, err := dbusAuthConnection(createBus)
- if err != nil {
- return nil, err
- }
-
- if err = conn.Hello(); err != nil {
- conn.Close()
- return nil, err
- }
-
- return conn, nil
-}
-
-func systemdObject(conn *dbus.Conn) dbus.BusObject {
- return conn.Object("org.freedesktop.systemd1", dbus.ObjectPath("/org/freedesktop/systemd1"))
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/methods.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/methods.go
deleted file mode 100644
index ab614c7c..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/methods.go
+++ /dev/null
@@ -1,410 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// 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 dbus
-
-import (
- "errors"
- "path"
- "strconv"
-
- "github.com/godbus/dbus"
-)
-
-func (c *Conn) jobComplete(signal *dbus.Signal) {
- var id uint32
- var job dbus.ObjectPath
- var unit string
- var result string
- dbus.Store(signal.Body, &id, &job, &unit, &result)
- c.jobListener.Lock()
- out, ok := c.jobListener.jobs[job]
- if ok {
- out <- result
- delete(c.jobListener.jobs, job)
- }
- c.jobListener.Unlock()
-}
-
-func (c *Conn) startJob(ch chan<- string, job string, args ...interface{}) (int, error) {
- if ch != nil {
- c.jobListener.Lock()
- defer c.jobListener.Unlock()
- }
-
- var p dbus.ObjectPath
- err := c.sysobj.Call(job, 0, args...).Store(&p)
- if err != nil {
- return 0, err
- }
-
- if ch != nil {
- c.jobListener.jobs[p] = ch
- }
-
- // ignore error since 0 is fine if conversion fails
- jobID, _ := strconv.Atoi(path.Base(string(p)))
-
- return jobID, nil
-}
-
-// StartUnit enqueues a start job and depending jobs, if any (unless otherwise
-// specified by the mode string).
-//
-// Takes the unit to activate, plus a mode string. The mode needs to be one of
-// replace, fail, isolate, ignore-dependencies, ignore-requirements. If
-// "replace" the call will start the unit and its dependencies, possibly
-// replacing already queued jobs that conflict with this. If "fail" the call
-// will start the unit and its dependencies, but will fail if this would change
-// an already queued job. If "isolate" the call will start the unit in question
-// and terminate all units that aren't dependencies of it. If
-// "ignore-dependencies" it will start a unit but ignore all its dependencies.
-// If "ignore-requirements" it will start a unit but only ignore the
-// requirement dependencies. It is not recommended to make use of the latter
-// two options.
-//
-// If the provided channel is non-nil, a result string will be sent to it upon
-// job completion: one of done, canceled, timeout, failed, dependency, skipped.
-// done indicates successful execution of a job. canceled indicates that a job
-// has been canceled before it finished execution. timeout indicates that the
-// job timeout was reached. failed indicates that the job failed. dependency
-// indicates that a job this job has been depending on failed and the job hence
-// has been removed too. skipped indicates that a job was skipped because it
-// didn't apply to the units current state.
-//
-// If no error occurs, the ID of the underlying systemd job will be returned. There
-// does exist the possibility for no error to be returned, but for the returned job
-// ID to be 0. In this case, the actual underlying ID is not 0 and this datapoint
-// should not be considered authoritative.
-//
-// If an error does occur, it will be returned to the user alongside a job ID of 0.
-func (c *Conn) StartUnit(name string, mode string, ch chan<- string) (int, error) {
- return c.startJob(ch, "org.freedesktop.systemd1.Manager.StartUnit", name, mode)
-}
-
-// StopUnit is similar to StartUnit but stops the specified unit rather
-// than starting it.
-func (c *Conn) StopUnit(name string, mode string, ch chan<- string) (int, error) {
- return c.startJob(ch, "org.freedesktop.systemd1.Manager.StopUnit", name, mode)
-}
-
-// ReloadUnit reloads a unit. Reloading is done only if the unit is already running and fails otherwise.
-func (c *Conn) ReloadUnit(name string, mode string, ch chan<- string) (int, error) {
- return c.startJob(ch, "org.freedesktop.systemd1.Manager.ReloadUnit", name, mode)
-}
-
-// RestartUnit restarts a service. If a service is restarted that isn't
-// running it will be started.
-func (c *Conn) RestartUnit(name string, mode string, ch chan<- string) (int, error) {
- return c.startJob(ch, "org.freedesktop.systemd1.Manager.RestartUnit", name, mode)
-}
-
-// TryRestartUnit is like RestartUnit, except that a service that isn't running
-// is not affected by the restart.
-func (c *Conn) TryRestartUnit(name string, mode string, ch chan<- string) (int, error) {
- return c.startJob(ch, "org.freedesktop.systemd1.Manager.TryRestartUnit", name, mode)
-}
-
-// ReloadOrRestart attempts a reload if the unit supports it and use a restart
-// otherwise.
-func (c *Conn) ReloadOrRestartUnit(name string, mode string, ch chan<- string) (int, error) {
- return c.startJob(ch, "org.freedesktop.systemd1.Manager.ReloadOrRestartUnit", name, mode)
-}
-
-// ReloadOrTryRestart attempts a reload if the unit supports it and use a "Try"
-// flavored restart otherwise.
-func (c *Conn) ReloadOrTryRestartUnit(name string, mode string, ch chan<- string) (int, error) {
- return c.startJob(ch, "org.freedesktop.systemd1.Manager.ReloadOrTryRestartUnit", name, mode)
-}
-
-// StartTransientUnit() may be used to create and start a transient unit, which
-// will be released as soon as it is not running or referenced anymore or the
-// system is rebooted. name is the unit name including suffix, and must be
-// unique. mode is the same as in StartUnit(), properties contains properties
-// of the unit.
-func (c *Conn) StartTransientUnit(name string, mode string, properties []Property, ch chan<- string) (int, error) {
- return c.startJob(ch, "org.freedesktop.systemd1.Manager.StartTransientUnit", name, mode, properties, make([]PropertyCollection, 0))
-}
-
-// KillUnit takes the unit name and a UNIX signal number to send. All of the unit's
-// processes are killed.
-func (c *Conn) KillUnit(name string, signal int32) {
- c.sysobj.Call("org.freedesktop.systemd1.Manager.KillUnit", 0, name, "all", signal).Store()
-}
-
-// ResetFailedUnit resets the "failed" state of a specific unit.
-func (c *Conn) ResetFailedUnit(name string) error {
- return c.sysobj.Call("org.freedesktop.systemd1.Manager.ResetFailedUnit", 0, name).Store()
-}
-
-// getProperties takes the unit name and returns all of its dbus object properties, for the given dbus interface
-func (c *Conn) getProperties(unit string, dbusInterface string) (map[string]interface{}, error) {
- var err error
- var props map[string]dbus.Variant
-
- path := unitPath(unit)
- if !path.IsValid() {
- return nil, errors.New("invalid unit name: " + unit)
- }
-
- obj := c.sysconn.Object("org.freedesktop.systemd1", path)
- err = obj.Call("org.freedesktop.DBus.Properties.GetAll", 0, dbusInterface).Store(&props)
- if err != nil {
- return nil, err
- }
-
- out := make(map[string]interface{}, len(props))
- for k, v := range props {
- out[k] = v.Value()
- }
-
- return out, nil
-}
-
-// GetUnitProperties takes the unit name and returns all of its dbus object properties.
-func (c *Conn) GetUnitProperties(unit string) (map[string]interface{}, error) {
- return c.getProperties(unit, "org.freedesktop.systemd1.Unit")
-}
-
-func (c *Conn) getProperty(unit string, dbusInterface string, propertyName string) (*Property, error) {
- var err error
- var prop dbus.Variant
-
- path := unitPath(unit)
- if !path.IsValid() {
- return nil, errors.New("invalid unit name: " + unit)
- }
-
- obj := c.sysconn.Object("org.freedesktop.systemd1", path)
- err = obj.Call("org.freedesktop.DBus.Properties.Get", 0, dbusInterface, propertyName).Store(&prop)
- if err != nil {
- return nil, err
- }
-
- return &Property{Name: propertyName, Value: prop}, nil
-}
-
-func (c *Conn) GetUnitProperty(unit string, propertyName string) (*Property, error) {
- return c.getProperty(unit, "org.freedesktop.systemd1.Unit", propertyName)
-}
-
-// GetUnitTypeProperties returns the extra properties for a unit, specific to the unit type.
-// Valid values for unitType: Service, Socket, Target, Device, Mount, Automount, Snapshot, Timer, Swap, Path, Slice, Scope
-// return "dbus.Error: Unknown interface" if the unitType is not the correct type of the unit
-func (c *Conn) GetUnitTypeProperties(unit string, unitType string) (map[string]interface{}, error) {
- return c.getProperties(unit, "org.freedesktop.systemd1."+unitType)
-}
-
-// SetUnitProperties() may be used to modify certain unit properties at runtime.
-// Not all properties may be changed at runtime, but many resource management
-// settings (primarily those in systemd.cgroup(5)) may. The changes are applied
-// instantly, and stored on disk for future boots, unless runtime is true, in which
-// case the settings only apply until the next reboot. name is the name of the unit
-// to modify. properties are the settings to set, encoded as an array of property
-// name and value pairs.
-func (c *Conn) SetUnitProperties(name string, runtime bool, properties ...Property) error {
- return c.sysobj.Call("org.freedesktop.systemd1.Manager.SetUnitProperties", 0, name, runtime, properties).Store()
-}
-
-func (c *Conn) GetUnitTypeProperty(unit string, unitType string, propertyName string) (*Property, error) {
- return c.getProperty(unit, "org.freedesktop.systemd1."+unitType, propertyName)
-}
-
-// ListUnits returns an array with all currently loaded units. Note that
-// units may be known by multiple names at the same time, and hence there might
-// be more unit names loaded than actual units behind them.
-func (c *Conn) ListUnits() ([]UnitStatus, error) {
- result := make([][]interface{}, 0)
- err := c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnits", 0).Store(&result)
- if err != nil {
- return nil, err
- }
-
- resultInterface := make([]interface{}, len(result))
- for i := range result {
- resultInterface[i] = result[i]
- }
-
- status := make([]UnitStatus, len(result))
- statusInterface := make([]interface{}, len(status))
- for i := range status {
- statusInterface[i] = &status[i]
- }
-
- err = dbus.Store(resultInterface, statusInterface...)
- if err != nil {
- return nil, err
- }
-
- return status, nil
-}
-
-type UnitStatus struct {
- Name string // The primary unit name as string
- Description string // The human readable description string
- LoadState string // The load state (i.e. whether the unit file has been loaded successfully)
- ActiveState string // The active state (i.e. whether the unit is currently started or not)
- SubState string // The sub state (a more fine-grained version of the active state that is specific to the unit type, which the active state is not)
- Followed string // A unit that is being followed in its state by this unit, if there is any, otherwise the empty string.
- Path dbus.ObjectPath // The unit object path
- JobId uint32 // If there is a job queued for the job unit the numeric job id, 0 otherwise
- JobType string // The job type as string
- JobPath dbus.ObjectPath // The job object path
-}
-
-type LinkUnitFileChange EnableUnitFileChange
-
-// LinkUnitFiles() links unit files (that are located outside of the
-// usual unit search paths) into the unit search path.
-//
-// It takes a list of absolute paths to unit files to link and two
-// booleans. The first boolean controls whether the unit shall be
-// enabled for runtime only (true, /run), or persistently (false,
-// /etc).
-// The second controls whether symlinks pointing to other units shall
-// be replaced if necessary.
-//
-// This call returns a list of the changes made. The list consists of
-// structures with three strings: the type of the change (one of symlink
-// or unlink), the file name of the symlink and the destination of the
-// symlink.
-func (c *Conn) LinkUnitFiles(files []string, runtime bool, force bool) ([]LinkUnitFileChange, error) {
- result := make([][]interface{}, 0)
- err := c.sysobj.Call("org.freedesktop.systemd1.Manager.LinkUnitFiles", 0, files, runtime, force).Store(&result)
- if err != nil {
- return nil, err
- }
-
- resultInterface := make([]interface{}, len(result))
- for i := range result {
- resultInterface[i] = result[i]
- }
-
- changes := make([]LinkUnitFileChange, len(result))
- changesInterface := make([]interface{}, len(changes))
- for i := range changes {
- changesInterface[i] = &changes[i]
- }
-
- err = dbus.Store(resultInterface, changesInterface...)
- if err != nil {
- return nil, err
- }
-
- return changes, nil
-}
-
-// EnableUnitFiles() may be used to enable one or more units in the system (by
-// creating symlinks to them in /etc or /run).
-//
-// It takes a list of unit files to enable (either just file names or full
-// absolute paths if the unit files are residing outside the usual unit
-// search paths), and two booleans: the first controls whether the unit shall
-// be enabled for runtime only (true, /run), or persistently (false, /etc).
-// The second one controls whether symlinks pointing to other units shall
-// be replaced if necessary.
-//
-// This call returns one boolean and an array with the changes made. The
-// boolean signals whether the unit files contained any enablement
-// information (i.e. an [Install]) section. The changes list consists of
-// structures with three strings: the type of the change (one of symlink
-// or unlink), the file name of the symlink and the destination of the
-// symlink.
-func (c *Conn) EnableUnitFiles(files []string, runtime bool, force bool) (bool, []EnableUnitFileChange, error) {
- var carries_install_info bool
-
- result := make([][]interface{}, 0)
- err := c.sysobj.Call("org.freedesktop.systemd1.Manager.EnableUnitFiles", 0, files, runtime, force).Store(&carries_install_info, &result)
- if err != nil {
- return false, nil, err
- }
-
- resultInterface := make([]interface{}, len(result))
- for i := range result {
- resultInterface[i] = result[i]
- }
-
- changes := make([]EnableUnitFileChange, len(result))
- changesInterface := make([]interface{}, len(changes))
- for i := range changes {
- changesInterface[i] = &changes[i]
- }
-
- err = dbus.Store(resultInterface, changesInterface...)
- if err != nil {
- return false, nil, err
- }
-
- return carries_install_info, changes, nil
-}
-
-type EnableUnitFileChange struct {
- Type string // Type of the change (one of symlink or unlink)
- Filename string // File name of the symlink
- Destination string // Destination of the symlink
-}
-
-// DisableUnitFiles() may be used to disable one or more units in the system (by
-// removing symlinks to them from /etc or /run).
-//
-// It takes a list of unit files to disable (either just file names or full
-// absolute paths if the unit files are residing outside the usual unit
-// search paths), and one boolean: whether the unit was enabled for runtime
-// only (true, /run), or persistently (false, /etc).
-//
-// This call returns an array with the changes made. The changes list
-// consists of structures with three strings: the type of the change (one of
-// symlink or unlink), the file name of the symlink and the destination of the
-// symlink.
-func (c *Conn) DisableUnitFiles(files []string, runtime bool) ([]DisableUnitFileChange, error) {
- result := make([][]interface{}, 0)
- err := c.sysobj.Call("org.freedesktop.systemd1.Manager.DisableUnitFiles", 0, files, runtime).Store(&result)
- if err != nil {
- return nil, err
- }
-
- resultInterface := make([]interface{}, len(result))
- for i := range result {
- resultInterface[i] = result[i]
- }
-
- changes := make([]DisableUnitFileChange, len(result))
- changesInterface := make([]interface{}, len(changes))
- for i := range changes {
- changesInterface[i] = &changes[i]
- }
-
- err = dbus.Store(resultInterface, changesInterface...)
- if err != nil {
- return nil, err
- }
-
- return changes, nil
-}
-
-type DisableUnitFileChange struct {
- Type string // Type of the change (one of symlink or unlink)
- Filename string // File name of the symlink
- Destination string // Destination of the symlink
-}
-
-// Reload instructs systemd to scan for and reload unit files. This is
-// equivalent to a 'systemctl daemon-reload'.
-func (c *Conn) Reload() error {
- return c.sysobj.Call("org.freedesktop.systemd1.Manager.Reload", 0).Store()
-}
-
-func unitPath(name string) dbus.ObjectPath {
- return dbus.ObjectPath("/org/freedesktop/systemd1/unit/" + PathBusEscape(name))
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/properties.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/properties.go
deleted file mode 100644
index 75200115..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/properties.go
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// 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 dbus
-
-import (
- "github.com/godbus/dbus"
-)
-
-// From the systemd docs:
-//
-// The properties array of StartTransientUnit() may take many of the settings
-// that may also be configured in unit files. Not all parameters are currently
-// accepted though, but we plan to cover more properties with future release.
-// Currently you may set the Description, Slice and all dependency types of
-// units, as well as RemainAfterExit, ExecStart for service units,
-// TimeoutStopUSec and PIDs for scope units, and CPUAccounting, CPUShares,
-// BlockIOAccounting, BlockIOWeight, BlockIOReadBandwidth,
-// BlockIOWriteBandwidth, BlockIODeviceWeight, MemoryAccounting, MemoryLimit,
-// DevicePolicy, DeviceAllow for services/scopes/slices. These fields map
-// directly to their counterparts in unit files and as normal D-Bus object
-// properties. The exception here is the PIDs field of scope units which is
-// used for construction of the scope only and specifies the initial PIDs to
-// add to the scope object.
-
-type Property struct {
- Name string
- Value dbus.Variant
-}
-
-type PropertyCollection struct {
- Name string
- Properties []Property
-}
-
-type execStart struct {
- Path string // the binary path to execute
- Args []string // an array with all arguments to pass to the executed command, starting with argument 0
- UncleanIsFailure bool // a boolean whether it should be considered a failure if the process exits uncleanly
-}
-
-// PropExecStart sets the ExecStart service property. The first argument is a
-// slice with the binary path to execute followed by the arguments to pass to
-// the executed command. See
-// http://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart=
-func PropExecStart(command []string, uncleanIsFailure bool) Property {
- execStarts := []execStart{
- execStart{
- Path: command[0],
- Args: command,
- UncleanIsFailure: uncleanIsFailure,
- },
- }
-
- return Property{
- Name: "ExecStart",
- Value: dbus.MakeVariant(execStarts),
- }
-}
-
-// PropRemainAfterExit sets the RemainAfterExit service property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.service.html#RemainAfterExit=
-func PropRemainAfterExit(b bool) Property {
- return Property{
- Name: "RemainAfterExit",
- Value: dbus.MakeVariant(b),
- }
-}
-
-// PropDescription sets the Description unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit#Description=
-func PropDescription(desc string) Property {
- return Property{
- Name: "Description",
- Value: dbus.MakeVariant(desc),
- }
-}
-
-func propDependency(name string, units []string) Property {
- return Property{
- Name: name,
- Value: dbus.MakeVariant(units),
- }
-}
-
-// PropRequires sets the Requires unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Requires=
-func PropRequires(units ...string) Property {
- return propDependency("Requires", units)
-}
-
-// PropRequiresOverridable sets the RequiresOverridable unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiresOverridable=
-func PropRequiresOverridable(units ...string) Property {
- return propDependency("RequiresOverridable", units)
-}
-
-// PropRequisite sets the Requisite unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Requisite=
-func PropRequisite(units ...string) Property {
- return propDependency("Requisite", units)
-}
-
-// PropRequisiteOverridable sets the RequisiteOverridable unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequisiteOverridable=
-func PropRequisiteOverridable(units ...string) Property {
- return propDependency("RequisiteOverridable", units)
-}
-
-// PropWants sets the Wants unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Wants=
-func PropWants(units ...string) Property {
- return propDependency("Wants", units)
-}
-
-// PropBindsTo sets the BindsTo unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#BindsTo=
-func PropBindsTo(units ...string) Property {
- return propDependency("BindsTo", units)
-}
-
-// PropRequiredBy sets the RequiredBy unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiredBy=
-func PropRequiredBy(units ...string) Property {
- return propDependency("RequiredBy", units)
-}
-
-// PropRequiredByOverridable sets the RequiredByOverridable unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiredByOverridable=
-func PropRequiredByOverridable(units ...string) Property {
- return propDependency("RequiredByOverridable", units)
-}
-
-// PropWantedBy sets the WantedBy unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#WantedBy=
-func PropWantedBy(units ...string) Property {
- return propDependency("WantedBy", units)
-}
-
-// PropBoundBy sets the BoundBy unit property. See
-// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#BoundBy=
-func PropBoundBy(units ...string) Property {
- return propDependency("BoundBy", units)
-}
-
-// PropConflicts sets the Conflicts unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Conflicts=
-func PropConflicts(units ...string) Property {
- return propDependency("Conflicts", units)
-}
-
-// PropConflictedBy sets the ConflictedBy unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#ConflictedBy=
-func PropConflictedBy(units ...string) Property {
- return propDependency("ConflictedBy", units)
-}
-
-// PropBefore sets the Before unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Before=
-func PropBefore(units ...string) Property {
- return propDependency("Before", units)
-}
-
-// PropAfter sets the After unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#After=
-func PropAfter(units ...string) Property {
- return propDependency("After", units)
-}
-
-// PropOnFailure sets the OnFailure unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#OnFailure=
-func PropOnFailure(units ...string) Property {
- return propDependency("OnFailure", units)
-}
-
-// PropTriggers sets the Triggers unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Triggers=
-func PropTriggers(units ...string) Property {
- return propDependency("Triggers", units)
-}
-
-// PropTriggeredBy sets the TriggeredBy unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#TriggeredBy=
-func PropTriggeredBy(units ...string) Property {
- return propDependency("TriggeredBy", units)
-}
-
-// PropPropagatesReloadTo sets the PropagatesReloadTo unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#PropagatesReloadTo=
-func PropPropagatesReloadTo(units ...string) Property {
- return propDependency("PropagatesReloadTo", units)
-}
-
-// PropRequiresMountsFor sets the RequiresMountsFor unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiresMountsFor=
-func PropRequiresMountsFor(units ...string) Property {
- return propDependency("RequiresMountsFor", units)
-}
-
-// PropSlice sets the Slice unit property. See
-// http://www.freedesktop.org/software/systemd/man/systemd.resource-control.html#Slice=
-func PropSlice(slice string) Property {
- return Property{
- Name: "Slice",
- Value: dbus.MakeVariant(slice),
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/set.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/set.go
deleted file mode 100644
index f92e6fbe..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/set.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// 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 dbus
-
-type set struct {
- data map[string]bool
-}
-
-func (s *set) Add(value string) {
- s.data[value] = true
-}
-
-func (s *set) Remove(value string) {
- delete(s.data, value)
-}
-
-func (s *set) Contains(value string) (exists bool) {
- _, exists = s.data[value]
- return
-}
-
-func (s *set) Length() int {
- return len(s.data)
-}
-
-func (s *set) Values() (values []string) {
- for val, _ := range s.data {
- values = append(values, val)
- }
- return
-}
-
-func newSet() *set {
- return &set{make(map[string]bool)}
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/subscription.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/subscription.go
deleted file mode 100644
index 99645144..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/subscription.go
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// 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 dbus
-
-import (
- "errors"
- "time"
-
- "github.com/godbus/dbus"
-)
-
-const (
- cleanIgnoreInterval = int64(10 * time.Second)
- ignoreInterval = int64(30 * time.Millisecond)
-)
-
-// Subscribe sets up this connection to subscribe to all systemd dbus events.
-// This is required before calling SubscribeUnits. When the connection closes
-// systemd will automatically stop sending signals so there is no need to
-// explicitly call Unsubscribe().
-func (c *Conn) Subscribe() error {
- c.sigconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0,
- "type='signal',interface='org.freedesktop.systemd1.Manager',member='UnitNew'")
- c.sigconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0,
- "type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'")
-
- err := c.sigobj.Call("org.freedesktop.systemd1.Manager.Subscribe", 0).Store()
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// Unsubscribe this connection from systemd dbus events.
-func (c *Conn) Unsubscribe() error {
- err := c.sigobj.Call("org.freedesktop.systemd1.Manager.Unsubscribe", 0).Store()
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func (c *Conn) dispatch() {
- ch := make(chan *dbus.Signal, signalBuffer)
-
- c.sigconn.Signal(ch)
-
- go func() {
- for {
- signal, ok := <-ch
- if !ok {
- return
- }
-
- if signal.Name == "org.freedesktop.systemd1.Manager.JobRemoved" {
- c.jobComplete(signal)
- }
-
- if c.subscriber.updateCh == nil {
- continue
- }
-
- var unitPath dbus.ObjectPath
- switch signal.Name {
- case "org.freedesktop.systemd1.Manager.JobRemoved":
- unitName := signal.Body[2].(string)
- c.sysobj.Call("org.freedesktop.systemd1.Manager.GetUnit", 0, unitName).Store(&unitPath)
- case "org.freedesktop.systemd1.Manager.UnitNew":
- unitPath = signal.Body[1].(dbus.ObjectPath)
- case "org.freedesktop.DBus.Properties.PropertiesChanged":
- if signal.Body[0].(string) == "org.freedesktop.systemd1.Unit" {
- unitPath = signal.Path
- }
- }
-
- if unitPath == dbus.ObjectPath("") {
- continue
- }
-
- c.sendSubStateUpdate(unitPath)
- }
- }()
-}
-
-// Returns two unbuffered channels which will receive all changed units every
-// interval. Deleted units are sent as nil.
-func (c *Conn) SubscribeUnits(interval time.Duration) (<-chan map[string]*UnitStatus, <-chan error) {
- return c.SubscribeUnitsCustom(interval, 0, func(u1, u2 *UnitStatus) bool { return *u1 != *u2 }, nil)
-}
-
-// SubscribeUnitsCustom is like SubscribeUnits but lets you specify the buffer
-// size of the channels, the comparison function for detecting changes and a filter
-// function for cutting down on the noise that your channel receives.
-func (c *Conn) SubscribeUnitsCustom(interval time.Duration, buffer int, isChanged func(*UnitStatus, *UnitStatus) bool, filterUnit func(string) bool) (<-chan map[string]*UnitStatus, <-chan error) {
- old := make(map[string]*UnitStatus)
- statusChan := make(chan map[string]*UnitStatus, buffer)
- errChan := make(chan error, buffer)
-
- go func() {
- for {
- timerChan := time.After(interval)
-
- units, err := c.ListUnits()
- if err == nil {
- cur := make(map[string]*UnitStatus)
- for i := range units {
- if filterUnit != nil && filterUnit(units[i].Name) {
- continue
- }
- cur[units[i].Name] = &units[i]
- }
-
- // add all new or changed units
- changed := make(map[string]*UnitStatus)
- for n, u := range cur {
- if oldU, ok := old[n]; !ok || isChanged(oldU, u) {
- changed[n] = u
- }
- delete(old, n)
- }
-
- // add all deleted units
- for oldN := range old {
- changed[oldN] = nil
- }
-
- old = cur
-
- if len(changed) != 0 {
- statusChan <- changed
- }
- } else {
- errChan <- err
- }
-
- <-timerChan
- }
- }()
-
- return statusChan, errChan
-}
-
-type SubStateUpdate struct {
- UnitName string
- SubState string
-}
-
-// SetSubStateSubscriber writes to updateCh when any unit's substate changes.
-// Although this writes to updateCh on every state change, the reported state
-// may be more recent than the change that generated it (due to an unavoidable
-// race in the systemd dbus interface). That is, this method provides a good
-// way to keep a current view of all units' states, but is not guaranteed to
-// show every state transition they go through. Furthermore, state changes
-// will only be written to the channel with non-blocking writes. If updateCh
-// is full, it attempts to write an error to errCh; if errCh is full, the error
-// passes silently.
-func (c *Conn) SetSubStateSubscriber(updateCh chan<- *SubStateUpdate, errCh chan<- error) {
- c.subscriber.Lock()
- defer c.subscriber.Unlock()
- c.subscriber.updateCh = updateCh
- c.subscriber.errCh = errCh
-}
-
-func (c *Conn) sendSubStateUpdate(path dbus.ObjectPath) {
- c.subscriber.Lock()
- defer c.subscriber.Unlock()
-
- if c.shouldIgnore(path) {
- return
- }
-
- info, err := c.GetUnitProperties(string(path))
- if err != nil {
- select {
- case c.subscriber.errCh <- err:
- default:
- }
- }
-
- name := info["Id"].(string)
- substate := info["SubState"].(string)
-
- update := &SubStateUpdate{name, substate}
- select {
- case c.subscriber.updateCh <- update:
- default:
- select {
- case c.subscriber.errCh <- errors.New("update channel full!"):
- default:
- }
- }
-
- c.updateIgnore(path, info)
-}
-
-// The ignore functions work around a wart in the systemd dbus interface.
-// Requesting the properties of an unloaded unit will cause systemd to send a
-// pair of UnitNew/UnitRemoved signals. Because we need to get a unit's
-// properties on UnitNew (as that's the only indication of a new unit coming up
-// for the first time), we would enter an infinite loop if we did not attempt
-// to detect and ignore these spurious signals. The signal themselves are
-// indistinguishable from relevant ones, so we (somewhat hackishly) ignore an
-// unloaded unit's signals for a short time after requesting its properties.
-// This means that we will miss e.g. a transient unit being restarted
-// *immediately* upon failure and also a transient unit being started
-// immediately after requesting its status (with systemctl status, for example,
-// because this causes a UnitNew signal to be sent which then causes us to fetch
-// the properties).
-
-func (c *Conn) shouldIgnore(path dbus.ObjectPath) bool {
- t, ok := c.subscriber.ignore[path]
- return ok && t >= time.Now().UnixNano()
-}
-
-func (c *Conn) updateIgnore(path dbus.ObjectPath, info map[string]interface{}) {
- c.cleanIgnore()
-
- // unit is unloaded - it will trigger bad systemd dbus behavior
- if info["LoadState"].(string) == "not-found" {
- c.subscriber.ignore[path] = time.Now().UnixNano() + ignoreInterval
- }
-}
-
-// without this, ignore would grow unboundedly over time
-func (c *Conn) cleanIgnore() {
- now := time.Now().UnixNano()
- if c.subscriber.cleanIgnore < now {
- c.subscriber.cleanIgnore = now + cleanIgnoreInterval
-
- for p, t := range c.subscriber.ignore {
- if t < now {
- delete(c.subscriber.ignore, p)
- }
- }
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/subscription_set.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/subscription_set.go
deleted file mode 100644
index 5b408d58..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus/subscription_set.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// 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 dbus
-
-import (
- "time"
-)
-
-// SubscriptionSet returns a subscription set which is like conn.Subscribe but
-// can filter to only return events for a set of units.
-type SubscriptionSet struct {
- *set
- conn *Conn
-}
-
-func (s *SubscriptionSet) filter(unit string) bool {
- return !s.Contains(unit)
-}
-
-// Subscribe starts listening for dbus events for all of the units in the set.
-// Returns channels identical to conn.SubscribeUnits.
-func (s *SubscriptionSet) Subscribe() (<-chan map[string]*UnitStatus, <-chan error) {
- // TODO: Make fully evented by using systemd 209 with properties changed values
- return s.conn.SubscribeUnitsCustom(time.Second, 0,
- mismatchUnitStatus,
- func(unit string) bool { return s.filter(unit) },
- )
-}
-
-// NewSubscriptionSet returns a new subscription set.
-func (conn *Conn) NewSubscriptionSet() *SubscriptionSet {
- return &SubscriptionSet{newSet(), conn}
-}
-
-// mismatchUnitStatus returns true if the provided UnitStatus objects
-// are not equivalent. false is returned if the objects are equivalent.
-// Only the Name, Description and state-related fields are used in
-// the comparison.
-func mismatchUnitStatus(u1, u2 *UnitStatus) bool {
- return u1.Name != u2.Name ||
- u1.Description != u2.Description ||
- u1.LoadState != u2.LoadState ||
- u1.ActiveState != u2.ActiveState ||
- u1.SubState != u2.SubState
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/util/util.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/util/util.go
deleted file mode 100644
index 33832a1e..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/coreos/go-systemd/util/util.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// 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 util contains utility functions related to systemd that applications
-// can use to check things like whether systemd is running.
-package util
-
-import (
- "os"
-)
-
-// IsRunningSystemd checks whether the host was booted with systemd as its init
-// system. This functions similar to systemd's `sd_booted(3)`: internally, it
-// checks whether /run/systemd/system/ exists and is a directory.
-// http://www.freedesktop.org/software/systemd/man/sd_booted.html
-func IsRunningSystemd() bool {
- fi, err := os.Lstat("/run/systemd/system")
- if err != nil {
- return false
- }
- return fi.IsDir()
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/LICENSE b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/LICENSE
deleted file mode 100644
index c7a3f0cf..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/LICENSE
+++ /dev/null
@@ -1,191 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- https://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
-
- Copyright 2013-2015 Docker, Inc.
-
- 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
-
- https://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/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/NOTICE b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/NOTICE
deleted file mode 100644
index 6e6f469a..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/NOTICE
+++ /dev/null
@@ -1,19 +0,0 @@
-Docker
-Copyright 2012-2015 Docker, Inc.
-
-This product includes software developed at Docker, Inc. (https://www.docker.com).
-
-This product contains software (https://github.com/kr/pty) developed
-by Keith Rarick, licensed under the MIT License.
-
-The following is courtesy of our legal counsel:
-
-
-Use and transfer of Docker may be subject to certain restrictions by the
-United States and other governments.
-It is your responsibility to ensure that your use and/or transfer does not
-violate applicable laws.
-
-For more information, please see https://www.bis.doc.gov
-
-See also https://www.apache.org/dev/crypto.html and/or seek legal counsel.
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/contrib/syntax/vim/LICENSE b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/contrib/syntax/vim/LICENSE
deleted file mode 100644
index e67cdabd..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/contrib/syntax/vim/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2013 Honza Pokorny
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/docs/project/images/red_notice.png b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/docs/project/images/red_notice.png
deleted file mode 100644
index 8839723a..00000000
Binary files a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/docs/project/images/red_notice.png and /dev/null differ
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mflag/LICENSE b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mflag/LICENSE
deleted file mode 100644
index ac74d8f0..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mflag/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2014-2015 The Docker & Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags.go
deleted file mode 100644
index 17dbd7a6..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package mount
-
-import (
- "strings"
-)
-
-// Parse fstab type mount options into mount() flags
-// and device specific data
-func parseOptions(options string) (int, string) {
- var (
- flag int
- data []string
- )
-
- flags := map[string]struct {
- clear bool
- flag int
- }{
- "defaults": {false, 0},
- "ro": {false, RDONLY},
- "rw": {true, RDONLY},
- "suid": {true, NOSUID},
- "nosuid": {false, NOSUID},
- "dev": {true, NODEV},
- "nodev": {false, NODEV},
- "exec": {true, NOEXEC},
- "noexec": {false, NOEXEC},
- "sync": {false, SYNCHRONOUS},
- "async": {true, SYNCHRONOUS},
- "dirsync": {false, DIRSYNC},
- "remount": {false, REMOUNT},
- "mand": {false, MANDLOCK},
- "nomand": {true, MANDLOCK},
- "atime": {true, NOATIME},
- "noatime": {false, NOATIME},
- "diratime": {true, NODIRATIME},
- "nodiratime": {false, NODIRATIME},
- "bind": {false, BIND},
- "rbind": {false, RBIND},
- "unbindable": {false, UNBINDABLE},
- "runbindable": {false, RUNBINDABLE},
- "private": {false, PRIVATE},
- "rprivate": {false, RPRIVATE},
- "shared": {false, SHARED},
- "rshared": {false, RSHARED},
- "slave": {false, SLAVE},
- "rslave": {false, RSLAVE},
- "relatime": {false, RELATIME},
- "norelatime": {true, RELATIME},
- "strictatime": {false, STRICTATIME},
- "nostrictatime": {true, STRICTATIME},
- }
-
- for _, o := range strings.Split(options, ",") {
- // If the option does not exist in the flags table or the flag
- // is not supported on the platform,
- // then it is a data value for a specific fs type
- if f, exists := flags[o]; exists && f.flag != 0 {
- if f.clear {
- flag &= ^f.flag
- } else {
- flag |= f.flag
- }
- } else {
- data = append(data, o)
- }
- }
- return flag, strings.Join(data, ",")
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_freebsd.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_freebsd.go
deleted file mode 100644
index f166cb2f..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_freebsd.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// +build freebsd,cgo
-
-package mount
-
-/*
-#include
-*/
-import "C"
-
-const (
- // RDONLY will mount the filesystem as read-only.
- RDONLY = C.MNT_RDONLY
-
- // NOSUID will not allow set-user-identifier or set-group-identifier bits to
- // take effect.
- NOSUID = C.MNT_NOSUID
-
- // NOEXEC will not allow execution of any binaries on the mounted file system.
- NOEXEC = C.MNT_NOEXEC
-
- // SYNCHRONOUS will allow any I/O to the file system to be done synchronously.
- SYNCHRONOUS = C.MNT_SYNCHRONOUS
-
- // NOATIME will not update the file access time when reading from a file.
- NOATIME = C.MNT_NOATIME
-)
-
-// These flags are unsupported.
-const (
- BIND = 0
- DIRSYNC = 0
- MANDLOCK = 0
- NODEV = 0
- NODIRATIME = 0
- UNBINDABLE = 0
- RUNBINDABLE = 0
- PRIVATE = 0
- RPRIVATE = 0
- SHARED = 0
- RSHARED = 0
- SLAVE = 0
- RSLAVE = 0
- RBIND = 0
- RELATIVE = 0
- RELATIME = 0
- REMOUNT = 0
- STRICTATIME = 0
-)
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_linux.go
deleted file mode 100644
index 2f9f5c58..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_linux.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package mount
-
-import (
- "syscall"
-)
-
-const (
- // RDONLY will mount the file system read-only.
- RDONLY = syscall.MS_RDONLY
-
- // NOSUID will not allow set-user-identifier or set-group-identifier bits to
- // take effect.
- NOSUID = syscall.MS_NOSUID
-
- // NODEV will not interpret character or block special devices on the file
- // system.
- NODEV = syscall.MS_NODEV
-
- // NOEXEC will not allow execution of any binaries on the mounted file system.
- NOEXEC = syscall.MS_NOEXEC
-
- // SYNCHRONOUS will allow I/O to the file system to be done synchronously.
- SYNCHRONOUS = syscall.MS_SYNCHRONOUS
-
- // DIRSYNC will force all directory updates within the file system to be done
- // synchronously. This affects the following system calls: creat, link,
- // unlink, symlink, mkdir, rmdir, mknod and rename.
- DIRSYNC = syscall.MS_DIRSYNC
-
- // REMOUNT will attempt to remount an already-mounted file system. This is
- // commonly used to change the mount flags for a file system, especially to
- // make a readonly file system writeable. It does not change device or mount
- // point.
- REMOUNT = syscall.MS_REMOUNT
-
- // MANDLOCK will force mandatory locks on a filesystem.
- MANDLOCK = syscall.MS_MANDLOCK
-
- // NOATIME will not update the file access time when reading from a file.
- NOATIME = syscall.MS_NOATIME
-
- // NODIRATIME will not update the directory access time.
- NODIRATIME = syscall.MS_NODIRATIME
-
- // BIND remounts a subtree somewhere else.
- BIND = syscall.MS_BIND
-
- // RBIND remounts a subtree and all possible submounts somewhere else.
- RBIND = syscall.MS_BIND | syscall.MS_REC
-
- // UNBINDABLE creates a mount which cannot be cloned through a bind operation.
- UNBINDABLE = syscall.MS_UNBINDABLE
-
- // RUNBINDABLE marks the entire mount tree as UNBINDABLE.
- RUNBINDABLE = syscall.MS_UNBINDABLE | syscall.MS_REC
-
- // PRIVATE creates a mount which carries no propagation abilities.
- PRIVATE = syscall.MS_PRIVATE
-
- // RPRIVATE marks the entire mount tree as PRIVATE.
- RPRIVATE = syscall.MS_PRIVATE | syscall.MS_REC
-
- // SLAVE creates a mount which receives propagation from its master, but not
- // vice versa.
- SLAVE = syscall.MS_SLAVE
-
- // RSLAVE marks the entire mount tree as SLAVE.
- RSLAVE = syscall.MS_SLAVE | syscall.MS_REC
-
- // SHARED creates a mount which provides the ability to create mirrors of
- // that mount such that mounts and unmounts within any of the mirrors
- // propagate to the other mirrors.
- SHARED = syscall.MS_SHARED
-
- // RSHARED marks the entire mount tree as SHARED.
- RSHARED = syscall.MS_SHARED | syscall.MS_REC
-
- // RELATIME updates inode access times relative to modify or change time.
- RELATIME = syscall.MS_RELATIME
-
- // STRICTATIME allows to explicitly request full atime updates. This makes
- // it possible for the kernel to default to relatime or noatime but still
- // allow userspace to override it.
- STRICTATIME = syscall.MS_STRICTATIME
-)
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_unsupported.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_unsupported.go
deleted file mode 100644
index a90d3d11..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_unsupported.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// +build !linux,!freebsd freebsd,!cgo
-
-package mount
-
-// These flags are unsupported.
-const (
- BIND = 0
- DIRSYNC = 0
- MANDLOCK = 0
- NOATIME = 0
- NODEV = 0
- NODIRATIME = 0
- NOEXEC = 0
- NOSUID = 0
- UNBINDABLE = 0
- RUNBINDABLE = 0
- PRIVATE = 0
- RPRIVATE = 0
- SHARED = 0
- RSHARED = 0
- SLAVE = 0
- RSLAVE = 0
- RBIND = 0
- RELATIME = 0
- RELATIVE = 0
- REMOUNT = 0
- STRICTATIME = 0
- SYNCHRONOUS = 0
- RDONLY = 0
-)
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mount.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mount.go
deleted file mode 100644
index ed7216e5..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mount.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package mount
-
-import (
- "time"
-)
-
-// GetMounts retrieves a list of mounts for the current running process.
-func GetMounts() ([]*Info, error) {
- return parseMountTable()
-}
-
-// Mounted looks at /proc/self/mountinfo to determine of the specified
-// mountpoint has been mounted
-func Mounted(mountpoint string) (bool, error) {
- entries, err := parseMountTable()
- if err != nil {
- return false, err
- }
-
- // Search the table for the mountpoint
- for _, e := range entries {
- if e.Mountpoint == mountpoint {
- return true, nil
- }
- }
- return false, nil
-}
-
-// Mount will mount filesystem according to the specified configuration, on the
-// condition that the target path is *not* already mounted. Options must be
-// specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See
-// flags.go for supported option flags.
-func Mount(device, target, mType, options string) error {
- flag, _ := parseOptions(options)
- if flag&REMOUNT != REMOUNT {
- if mounted, err := Mounted(target); err != nil || mounted {
- return err
- }
- }
- return ForceMount(device, target, mType, options)
-}
-
-// ForceMount will mount a filesystem according to the specified configuration,
-// *regardless* if the target path is not already mounted. Options must be
-// specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See
-// flags.go for supported option flags.
-func ForceMount(device, target, mType, options string) error {
- flag, data := parseOptions(options)
- if err := mount(device, target, mType, uintptr(flag), data); err != nil {
- return err
- }
- return nil
-}
-
-// Unmount will unmount the target filesystem, so long as it is mounted.
-func Unmount(target string) error {
- if mounted, err := Mounted(target); err != nil || !mounted {
- return err
- }
- return ForceUnmount(target)
-}
-
-// ForceUnmount will force an unmount of the target filesystem, regardless if
-// it is mounted or not.
-func ForceUnmount(target string) (err error) {
- // Simple retry logic for unmount
- for i := 0; i < 10; i++ {
- if err = unmount(target, 0); err == nil {
- return nil
- }
- time.Sleep(100 * time.Millisecond)
- }
- return
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_freebsd.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_freebsd.go
deleted file mode 100644
index bb870e6f..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_freebsd.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package mount
-
-/*
-#include
-#include
-#include
-#include
-#include
-#include
-*/
-import "C"
-
-import (
- "fmt"
- "strings"
- "syscall"
- "unsafe"
-)
-
-func allocateIOVecs(options []string) []C.struct_iovec {
- out := make([]C.struct_iovec, len(options))
- for i, option := range options {
- out[i].iov_base = unsafe.Pointer(C.CString(option))
- out[i].iov_len = C.size_t(len(option) + 1)
- }
- return out
-}
-
-func mount(device, target, mType string, flag uintptr, data string) error {
- isNullFS := false
-
- xs := strings.Split(data, ",")
- for _, x := range xs {
- if x == "bind" {
- isNullFS = true
- }
- }
-
- options := []string{"fspath", target}
- if isNullFS {
- options = append(options, "fstype", "nullfs", "target", device)
- } else {
- options = append(options, "fstype", mType, "from", device)
- }
- rawOptions := allocateIOVecs(options)
- for _, rawOption := range rawOptions {
- defer C.free(rawOption.iov_base)
- }
-
- if errno := C.nmount(&rawOptions[0], C.uint(len(options)), C.int(flag)); errno != 0 {
- reason := C.GoString(C.strerror(*C.__error()))
- return fmt.Errorf("Failed to call nmount: %s", reason)
- }
- return nil
-}
-
-func unmount(target string, flag int) error {
- return syscall.Unmount(target, flag)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_linux.go
deleted file mode 100644
index dd4280c7..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_linux.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package mount
-
-import (
- "syscall"
-)
-
-func mount(device, target, mType string, flag uintptr, data string) error {
- if err := syscall.Mount(device, target, mType, flag, data); err != nil {
- return err
- }
-
- // If we have a bind mount or remount, remount...
- if flag&syscall.MS_BIND == syscall.MS_BIND && flag&syscall.MS_RDONLY == syscall.MS_RDONLY {
- return syscall.Mount(device, target, mType, flag|syscall.MS_REMOUNT, data)
- }
- return nil
-}
-
-func unmount(target string, flag int) error {
- return syscall.Unmount(target, flag)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_unsupported.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_unsupported.go
deleted file mode 100644
index eb93365e..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_unsupported.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// +build !linux,!freebsd freebsd,!cgo
-
-package mount
-
-func mount(device, target, mType string, flag uintptr, data string) error {
- panic("Not implemented")
-}
-
-func unmount(target string, flag int) error {
- panic("Not implemented")
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo.go
deleted file mode 100644
index e3fc3535..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package mount
-
-// Info reveals information about a particular mounted filesystem. This
-// struct is populated from the content in the /proc//mountinfo file.
-type Info struct {
- // ID is a unique identifier of the mount (may be reused after umount).
- ID int
-
- // Parent indicates the ID of the mount parent (or of self for the top of the
- // mount tree).
- Parent int
-
- // Major indicates one half of the device ID which identifies the device class.
- Major int
-
- // Minor indicates one half of the device ID which identifies a specific
- // instance of device.
- Minor int
-
- // Root of the mount within the filesystem.
- Root string
-
- // Mountpoint indicates the mount point relative to the process's root.
- Mountpoint string
-
- // Opts represents mount-specific options.
- Opts string
-
- // Optional represents optional fields.
- Optional string
-
- // Fstype indicates the type of filesystem, such as EXT3.
- Fstype string
-
- // Source indicates filesystem specific information or "none".
- Source string
-
- // VfsOpts represents per super block options.
- VfsOpts string
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_freebsd.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_freebsd.go
deleted file mode 100644
index 4f32edcd..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_freebsd.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package mount
-
-/*
-#include
-#include
-#include
-*/
-import "C"
-
-import (
- "fmt"
- "reflect"
- "unsafe"
-)
-
-// Parse /proc/self/mountinfo because comparing Dev and ino does not work from
-// bind mounts.
-func parseMountTable() ([]*Info, error) {
- var rawEntries *C.struct_statfs
-
- count := int(C.getmntinfo(&rawEntries, C.MNT_WAIT))
- if count == 0 {
- return nil, fmt.Errorf("Failed to call getmntinfo")
- }
-
- var entries []C.struct_statfs
- header := (*reflect.SliceHeader)(unsafe.Pointer(&entries))
- header.Cap = count
- header.Len = count
- header.Data = uintptr(unsafe.Pointer(rawEntries))
-
- var out []*Info
- for _, entry := range entries {
- var mountinfo Info
- mountinfo.Mountpoint = C.GoString(&entry.f_mntonname[0])
- mountinfo.Source = C.GoString(&entry.f_mntfromname[0])
- mountinfo.Fstype = C.GoString(&entry.f_fstypename[0])
- out = append(out, &mountinfo)
- }
- return out, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_linux.go
deleted file mode 100644
index be69fee1..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_linux.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// +build linux
-
-package mount
-
-import (
- "bufio"
- "fmt"
- "io"
- "os"
- "strings"
-)
-
-const (
- /* 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
- (1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11)
-
- (1) mount ID: unique identifier of the mount (may be reused after umount)
- (2) parent ID: ID of parent (or of self for the top of the mount tree)
- (3) major:minor: value of st_dev for files on filesystem
- (4) root: root of the mount within the filesystem
- (5) mount point: mount point relative to the process's root
- (6) mount options: per mount options
- (7) optional fields: zero or more fields of the form "tag[:value]"
- (8) separator: marks the end of the optional fields
- (9) filesystem type: name of filesystem of the form "type[.subtype]"
- (10) mount source: filesystem specific information or "none"
- (11) super options: per super block options*/
- mountinfoFormat = "%d %d %d:%d %s %s %s %s"
-)
-
-// Parse /proc/self/mountinfo because comparing Dev and ino does not work from
-// bind mounts
-func parseMountTable() ([]*Info, error) {
- f, err := os.Open("/proc/self/mountinfo")
- if err != nil {
- return nil, err
- }
- defer f.Close()
-
- return parseInfoFile(f)
-}
-
-func parseInfoFile(r io.Reader) ([]*Info, error) {
- var (
- s = bufio.NewScanner(r)
- out = []*Info{}
- )
-
- for s.Scan() {
- if err := s.Err(); err != nil {
- return nil, err
- }
-
- var (
- p = &Info{}
- text = s.Text()
- optionalFields string
- )
-
- if _, err := fmt.Sscanf(text, mountinfoFormat,
- &p.ID, &p.Parent, &p.Major, &p.Minor,
- &p.Root, &p.Mountpoint, &p.Opts, &optionalFields); err != nil {
- return nil, fmt.Errorf("Scanning '%s' failed: %s", text, err)
- }
- // Safe as mountinfo encodes mountpoints with spaces as \040.
- index := strings.Index(text, " - ")
- postSeparatorFields := strings.Fields(text[index+3:])
- if len(postSeparatorFields) < 3 {
- return nil, fmt.Errorf("Error found less than 3 fields post '-' in %q", text)
- }
-
- if optionalFields != "-" {
- p.Optional = optionalFields
- }
-
- p.Fstype = postSeparatorFields[0]
- p.Source = postSeparatorFields[1]
- p.VfsOpts = strings.Join(postSeparatorFields[2:], " ")
- out = append(out, p)
- }
- return out, nil
-}
-
-// PidMountInfo collects the mounts for a specific process ID. If the process
-// ID is unknown, it is better to use `GetMounts` which will inspect
-// "/proc/self/mountinfo" instead.
-func PidMountInfo(pid int) ([]*Info, error) {
- f, err := os.Open(fmt.Sprintf("/proc/%d/mountinfo", pid))
- if err != nil {
- return nil, err
- }
- defer f.Close()
-
- return parseInfoFile(f)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_unsupported.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_unsupported.go
deleted file mode 100644
index 8245f01d..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_unsupported.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// +build !linux,!freebsd freebsd,!cgo
-
-package mount
-
-import (
- "fmt"
- "runtime"
-)
-
-func parseMountTable() ([]*Info, error) {
- return nil, fmt.Errorf("mount.parseMountTable is not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/sharedsubtree_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/sharedsubtree_linux.go
deleted file mode 100644
index 47303bbc..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/sharedsubtree_linux.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// +build linux
-
-package mount
-
-// MakeShared ensures a mounted filesystem has the SHARED mount option enabled.
-// See the supported options in flags.go for further reference.
-func MakeShared(mountPoint string) error {
- return ensureMountedAs(mountPoint, "shared")
-}
-
-// MakeRShared ensures a mounted filesystem has the RSHARED mount option enabled.
-// See the supported options in flags.go for further reference.
-func MakeRShared(mountPoint string) error {
- return ensureMountedAs(mountPoint, "rshared")
-}
-
-// MakePrivate ensures a mounted filesystem has the PRIVATE mount option enabled.
-// See the supported options in flags.go for further reference.
-func MakePrivate(mountPoint string) error {
- return ensureMountedAs(mountPoint, "private")
-}
-
-// MakeRPrivate ensures a mounted filesystem has the RPRIVATE mount option
-// enabled. See the supported options in flags.go for further reference.
-func MakeRPrivate(mountPoint string) error {
- return ensureMountedAs(mountPoint, "rprivate")
-}
-
-// MakeSlave ensures a mounted filesystem has the SLAVE mount option enabled.
-// See the supported options in flags.go for further reference.
-func MakeSlave(mountPoint string) error {
- return ensureMountedAs(mountPoint, "slave")
-}
-
-// MakeRSlave ensures a mounted filesystem has the RSLAVE mount option enabled.
-// See the supported options in flags.go for further reference.
-func MakeRSlave(mountPoint string) error {
- return ensureMountedAs(mountPoint, "rslave")
-}
-
-// MakeUnbindable ensures a mounted filesystem has the UNBINDABLE mount option
-// enabled. See the supported options in flags.go for further reference.
-func MakeUnbindable(mountPoint string) error {
- return ensureMountedAs(mountPoint, "unbindable")
-}
-
-// MakeRUnbindable ensures a mounted filesystem has the RUNBINDABLE mount
-// option enabled. See the supported options in flags.go for further reference.
-func MakeRUnbindable(mountPoint string) error {
- return ensureMountedAs(mountPoint, "runbindable")
-}
-
-func ensureMountedAs(mountPoint, options string) error {
- mounted, err := Mounted(mountPoint)
- if err != nil {
- return err
- }
-
- if !mounted {
- if err := Mount(mountPoint, mountPoint, "none", "bind,rw"); err != nil {
- return err
- }
- }
- mounted, err = Mounted(mountPoint)
- if err != nil {
- return err
- }
-
- return ForceMount("", mountPoint, "none", options)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/LICENSE.APACHE b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/LICENSE.APACHE
deleted file mode 100644
index 9e4bd4db..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/LICENSE.APACHE
+++ /dev/null
@@ -1,191 +0,0 @@
-
- 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
-
- Copyright 2014-2015 Docker, Inc.
-
- 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/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/LICENSE.BSD b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/LICENSE.BSD
deleted file mode 100644
index ac74d8f0..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/LICENSE.BSD
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2014-2015 The Docker & Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/README.md b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/README.md
deleted file mode 100644
index 0d1dbb70..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-Package symlink implements EvalSymlinksInScope which is an extension of filepath.EvalSymlinks
-from the [Go standard library](https://golang.org/pkg/path/filepath).
-
-The code from filepath.EvalSymlinks has been adapted in fs.go.
-Please read the LICENSE.BSD file that governs fs.go and LICENSE.APACHE for fs_test.go.
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/fs.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/fs.go
deleted file mode 100644
index b4bdff24..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/fs.go
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.BSD file.
-
-// This code is a modified version of path/filepath/symlink.go from the Go standard library.
-
-package symlink
-
-import (
- "bytes"
- "errors"
- "os"
- "path/filepath"
- "strings"
-)
-
-// FollowSymlinkInScope is a wrapper around evalSymlinksInScope that returns an absolute path
-func FollowSymlinkInScope(path, root string) (string, error) {
- path, err := filepath.Abs(path)
- if err != nil {
- return "", err
- }
- root, err = filepath.Abs(root)
- if err != nil {
- return "", err
- }
- return evalSymlinksInScope(path, root)
-}
-
-// evalSymlinksInScope will evaluate symlinks in `path` within a scope `root` and return
-// a result guaranteed to be contained within the scope `root`, at the time of the call.
-// Symlinks in `root` are not evaluated and left as-is.
-// Errors encountered while attempting to evaluate symlinks in path will be returned.
-// Non-existing paths are valid and do not constitute an error.
-// `path` has to contain `root` as a prefix, or else an error will be returned.
-// Trying to break out from `root` does not constitute an error.
-//
-// Example:
-// If /foo/bar -> /outside,
-// FollowSymlinkInScope("/foo/bar", "/foo") == "/foo/outside" instead of "/oustide"
-//
-// IMPORTANT: it is the caller's responsibility to call evalSymlinksInScope *after* relevant symlinks
-// are created and not to create subsequently, additional symlinks that could potentially make a
-// previously-safe path, unsafe. Example: if /foo/bar does not exist, evalSymlinksInScope("/foo/bar", "/foo")
-// would return "/foo/bar". If one makes /foo/bar a symlink to /baz subsequently, then "/foo/bar" should
-// no longer be considered safely contained in "/foo".
-func evalSymlinksInScope(path, root string) (string, error) {
- root = filepath.Clean(root)
- if path == root {
- return path, nil
- }
- if !strings.HasPrefix(path, root) {
- return "", errors.New("evalSymlinksInScope: " + path + " is not in " + root)
- }
- const maxIter = 255
- originalPath := path
- // given root of "/a" and path of "/a/b/../../c" we want path to be "/b/../../c"
- path = path[len(root):]
- if root == string(filepath.Separator) {
- path = string(filepath.Separator) + path
- }
- if !strings.HasPrefix(path, string(filepath.Separator)) {
- return "", errors.New("evalSymlinksInScope: " + path + " is not in " + root)
- }
- path = filepath.Clean(path)
- // consume path by taking each frontmost path element,
- // expanding it if it's a symlink, and appending it to b
- var b bytes.Buffer
- // b here will always be considered to be the "current absolute path inside
- // root" when we append paths to it, we also append a slash and use
- // filepath.Clean after the loop to trim the trailing slash
- for n := 0; path != ""; n++ {
- if n > maxIter {
- return "", errors.New("evalSymlinksInScope: too many links in " + originalPath)
- }
-
- // find next path component, p
- i := strings.IndexRune(path, filepath.Separator)
- var p string
- if i == -1 {
- p, path = path, ""
- } else {
- p, path = path[:i], path[i+1:]
- }
-
- if p == "" {
- continue
- }
-
- // this takes a b.String() like "b/../" and a p like "c" and turns it
- // into "/b/../c" which then gets filepath.Cleaned into "/c" and then
- // root gets prepended and we Clean again (to remove any trailing slash
- // if the first Clean gave us just "/")
- cleanP := filepath.Clean(string(filepath.Separator) + b.String() + p)
- if cleanP == string(filepath.Separator) {
- // never Lstat "/" itself
- b.Reset()
- continue
- }
- fullP := filepath.Clean(root + cleanP)
-
- fi, err := os.Lstat(fullP)
- if os.IsNotExist(err) {
- // if p does not exist, accept it
- b.WriteString(p)
- b.WriteRune(filepath.Separator)
- continue
- }
- if err != nil {
- return "", err
- }
- if fi.Mode()&os.ModeSymlink == 0 {
- b.WriteString(p + string(filepath.Separator))
- continue
- }
-
- // it's a symlink, put it at the front of path
- dest, err := os.Readlink(fullP)
- if err != nil {
- return "", err
- }
- if filepath.IsAbs(dest) {
- b.Reset()
- }
- path = dest + string(filepath.Separator) + path
- }
-
- // see note above on "fullP := ..." for why this is double-cleaned and
- // what's happening here
- return filepath.Clean(root + filepath.Clean(string(filepath.Separator)+b.String())), nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/tc_linux_cgo.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/tc_linux_cgo.go
deleted file mode 100644
index d47cf59b..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/tc_linux_cgo.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// +build linux,cgo
-
-package term
-
-import (
- "syscall"
- "unsafe"
-)
-
-// #include
-import "C"
-
-type Termios syscall.Termios
-
-// MakeRaw put the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd uintptr) (*State, error) {
- var oldState State
- if err := tcget(fd, &oldState.termios); err != 0 {
- return nil, err
- }
-
- newState := oldState.termios
-
- C.cfmakeraw((*C.struct_termios)(unsafe.Pointer(&newState)))
- newState.Oflag = newState.Oflag | C.OPOST
- if err := tcset(fd, &newState); err != 0 {
- return nil, err
- }
- return &oldState, nil
-}
-
-func tcget(fd uintptr, p *Termios) syscall.Errno {
- ret, err := C.tcgetattr(C.int(fd), (*C.struct_termios)(unsafe.Pointer(p)))
- if ret != 0 {
- return err.(syscall.Errno)
- }
- return 0
-}
-
-func tcset(fd uintptr, p *Termios) syscall.Errno {
- ret, err := C.tcsetattr(C.int(fd), C.TCSANOW, (*C.struct_termios)(unsafe.Pointer(p)))
- if ret != 0 {
- return err.(syscall.Errno)
- }
- return 0
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/tc_other.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/tc_other.go
deleted file mode 100644
index 266039ba..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/tc_other.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// +build !windows
-// +build !linux !cgo
-
-package term
-
-import (
- "syscall"
- "unsafe"
-)
-
-func tcget(fd uintptr, p *Termios) syscall.Errno {
- _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(p)))
- return err
-}
-
-func tcset(fd uintptr, p *Termios) syscall.Errno {
- _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(p)))
- return err
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term.go
deleted file mode 100644
index b945a3dc..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term.go
+++ /dev/null
@@ -1,118 +0,0 @@
-// +build !windows
-
-package term
-
-import (
- "errors"
- "io"
- "os"
- "os/signal"
- "syscall"
- "unsafe"
-)
-
-var (
- ErrInvalidState = errors.New("Invalid terminal state")
-)
-
-type State struct {
- termios Termios
-}
-
-type Winsize struct {
- Height uint16
- Width uint16
- x uint16
- y uint16
-}
-
-func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
- return os.Stdin, os.Stdout, os.Stderr
-}
-
-func GetFdInfo(in interface{}) (uintptr, bool) {
- var inFd uintptr
- var isTerminalIn bool
- if file, ok := in.(*os.File); ok {
- inFd = file.Fd()
- isTerminalIn = IsTerminal(inFd)
- }
- return inFd, isTerminalIn
-}
-
-func GetWinsize(fd uintptr) (*Winsize, error) {
- ws := &Winsize{}
- _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(ws)))
- // Skipp errno = 0
- if err == 0 {
- return ws, nil
- }
- return ws, err
-}
-
-func SetWinsize(fd uintptr, ws *Winsize) error {
- _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(ws)))
- // Skipp errno = 0
- if err == 0 {
- return nil
- }
- return err
-}
-
-// IsTerminal returns true if the given file descriptor is a terminal.
-func IsTerminal(fd uintptr) bool {
- var termios Termios
- return tcget(fd, &termios) == 0
-}
-
-// Restore restores the terminal connected to the given file descriptor to a
-// previous state.
-func RestoreTerminal(fd uintptr, state *State) error {
- if state == nil {
- return ErrInvalidState
- }
- if err := tcset(fd, &state.termios); err != 0 {
- return err
- }
- return nil
-}
-
-func SaveState(fd uintptr) (*State, error) {
- var oldState State
- if err := tcget(fd, &oldState.termios); err != 0 {
- return nil, err
- }
-
- return &oldState, nil
-}
-
-func DisableEcho(fd uintptr, state *State) error {
- newState := state.termios
- newState.Lflag &^= syscall.ECHO
-
- if err := tcset(fd, &newState); err != 0 {
- return err
- }
- handleInterrupt(fd, state)
- return nil
-}
-
-func SetRawTerminal(fd uintptr) (*State, error) {
- oldState, err := MakeRaw(fd)
- if err != nil {
- return nil, err
- }
- handleInterrupt(fd, oldState)
- return oldState, err
-}
-
-func handleInterrupt(fd uintptr, state *State) {
- sigchan := make(chan os.Signal, 1)
- signal.Notify(sigchan, os.Interrupt)
-
- go func() {
- _ = <-sigchan
- RestoreTerminal(fd, state)
- os.Exit(0)
- }()
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term_windows.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term_windows.go
deleted file mode 100644
index f7fa1b3a..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term_windows.go
+++ /dev/null
@@ -1,139 +0,0 @@
-// +build windows
-
-package term
-
-import (
- "io"
- "os"
-
- "github.com/Sirupsen/logrus"
- "github.com/docker/docker/pkg/term/winconsole"
-)
-
-// State holds the console mode for the terminal.
-type State struct {
- mode uint32
-}
-
-// Winsize is used for window size.
-type Winsize struct {
- Height uint16
- Width uint16
- x uint16
- y uint16
-}
-
-func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
- switch {
- case os.Getenv("ConEmuANSI") == "ON":
- // The ConEmu shell emulates ANSI well by default.
- return os.Stdin, os.Stdout, os.Stderr
- case os.Getenv("MSYSTEM") != "":
- // MSYS (mingw) does not emulate ANSI well.
- return winconsole.WinConsoleStreams()
- default:
- return winconsole.WinConsoleStreams()
- }
-}
-
-// GetFdInfo returns file descriptor and bool indicating whether the file is a terminal.
-func GetFdInfo(in interface{}) (uintptr, bool) {
- return winconsole.GetHandleInfo(in)
-}
-
-// GetWinsize retrieves the window size of the terminal connected to the passed file descriptor.
-func GetWinsize(fd uintptr) (*Winsize, error) {
- info, err := winconsole.GetConsoleScreenBufferInfo(fd)
- if err != nil {
- return nil, err
- }
-
- // TODO(azlinux): Set the pixel width / height of the console (currently unused by any caller)
- return &Winsize{
- Width: uint16(info.Window.Right - info.Window.Left + 1),
- Height: uint16(info.Window.Bottom - info.Window.Top + 1),
- x: 0,
- y: 0}, nil
-}
-
-// SetWinsize sets the size of the given terminal connected to the passed file descriptor.
-func SetWinsize(fd uintptr, ws *Winsize) error {
- // TODO(azlinux): Implement SetWinsize
- logrus.Debugf("[windows] SetWinsize: WARNING -- Unsupported method invoked")
- return nil
-}
-
-// IsTerminal returns true if the given file descriptor is a terminal.
-func IsTerminal(fd uintptr) bool {
- return winconsole.IsConsole(fd)
-}
-
-// RestoreTerminal restores the terminal connected to the given file descriptor to a
-// previous state.
-func RestoreTerminal(fd uintptr, state *State) error {
- return winconsole.SetConsoleMode(fd, state.mode)
-}
-
-// SaveState saves the state of the terminal connected to the given file descriptor.
-func SaveState(fd uintptr) (*State, error) {
- mode, e := winconsole.GetConsoleMode(fd)
- if e != nil {
- return nil, e
- }
- return &State{mode}, nil
-}
-
-// DisableEcho disables echo for the terminal connected to the given file descriptor.
-// -- See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx
-func DisableEcho(fd uintptr, state *State) error {
- mode := state.mode
- mode &^= winconsole.ENABLE_ECHO_INPUT
- mode |= winconsole.ENABLE_PROCESSED_INPUT | winconsole.ENABLE_LINE_INPUT
- // TODO(azlinux): Core code registers a goroutine to catch os.Interrupt and reset the terminal state.
- return winconsole.SetConsoleMode(fd, mode)
-}
-
-// SetRawTerminal puts the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func SetRawTerminal(fd uintptr) (*State, error) {
- state, err := MakeRaw(fd)
- if err != nil {
- return nil, err
- }
- // TODO(azlinux): Core code registers a goroutine to catch os.Interrupt and reset the terminal state.
- return state, err
-}
-
-// MakeRaw puts the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd uintptr) (*State, error) {
- state, err := SaveState(fd)
- if err != nil {
- return nil, err
- }
-
- // See
- // -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
- // -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx
- mode := state.mode
-
- // Disable these modes
- mode &^= winconsole.ENABLE_ECHO_INPUT
- mode &^= winconsole.ENABLE_LINE_INPUT
- mode &^= winconsole.ENABLE_MOUSE_INPUT
- mode &^= winconsole.ENABLE_WINDOW_INPUT
- mode &^= winconsole.ENABLE_PROCESSED_INPUT
-
- // Enable these modes
- mode |= winconsole.ENABLE_EXTENDED_FLAGS
- mode |= winconsole.ENABLE_INSERT_MODE
- mode |= winconsole.ENABLE_QUICK_EDIT_MODE
-
- err = winconsole.SetConsoleMode(fd, mode)
- if err != nil {
- return nil, err
- }
- return state, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_darwin.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_darwin.go
deleted file mode 100644
index 11cd70d1..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_darwin.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package term
-
-import (
- "syscall"
- "unsafe"
-)
-
-const (
- getTermios = syscall.TIOCGETA
- setTermios = syscall.TIOCSETA
-
- IGNBRK = syscall.IGNBRK
- PARMRK = syscall.PARMRK
- INLCR = syscall.INLCR
- IGNCR = syscall.IGNCR
- ECHONL = syscall.ECHONL
- CSIZE = syscall.CSIZE
- ICRNL = syscall.ICRNL
- ISTRIP = syscall.ISTRIP
- PARENB = syscall.PARENB
- ECHO = syscall.ECHO
- ICANON = syscall.ICANON
- ISIG = syscall.ISIG
- IXON = syscall.IXON
- BRKINT = syscall.BRKINT
- INPCK = syscall.INPCK
- OPOST = syscall.OPOST
- CS8 = syscall.CS8
- IEXTEN = syscall.IEXTEN
-)
-
-type Termios struct {
- Iflag uint64
- Oflag uint64
- Cflag uint64
- Lflag uint64
- Cc [20]byte
- Ispeed uint64
- Ospeed uint64
-}
-
-// MakeRaw put the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd uintptr) (*State, error) {
- var oldState State
- if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
- return nil, err
- }
-
- newState := oldState.termios
- newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON)
- newState.Oflag &^= OPOST
- newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN)
- newState.Cflag &^= (CSIZE | PARENB)
- newState.Cflag |= CS8
- newState.Cc[syscall.VMIN] = 1
- newState.Cc[syscall.VTIME] = 0
-
- if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
- return nil, err
- }
-
- return &oldState, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_freebsd.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_freebsd.go
deleted file mode 100644
index ed365957..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_freebsd.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package term
-
-import (
- "syscall"
- "unsafe"
-)
-
-const (
- getTermios = syscall.TIOCGETA
- setTermios = syscall.TIOCSETA
-
- IGNBRK = syscall.IGNBRK
- PARMRK = syscall.PARMRK
- INLCR = syscall.INLCR
- IGNCR = syscall.IGNCR
- ECHONL = syscall.ECHONL
- CSIZE = syscall.CSIZE
- ICRNL = syscall.ICRNL
- ISTRIP = syscall.ISTRIP
- PARENB = syscall.PARENB
- ECHO = syscall.ECHO
- ICANON = syscall.ICANON
- ISIG = syscall.ISIG
- IXON = syscall.IXON
- BRKINT = syscall.BRKINT
- INPCK = syscall.INPCK
- OPOST = syscall.OPOST
- CS8 = syscall.CS8
- IEXTEN = syscall.IEXTEN
-)
-
-type Termios struct {
- Iflag uint32
- Oflag uint32
- Cflag uint32
- Lflag uint32
- Cc [20]byte
- Ispeed uint32
- Ospeed uint32
-}
-
-// MakeRaw put the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd uintptr) (*State, error) {
- var oldState State
- if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
- return nil, err
- }
-
- newState := oldState.termios
- newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON)
- newState.Oflag &^= OPOST
- newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN)
- newState.Cflag &^= (CSIZE | PARENB)
- newState.Cflag |= CS8
- newState.Cc[syscall.VMIN] = 1
- newState.Cc[syscall.VTIME] = 0
-
- if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
- return nil, err
- }
-
- return &oldState, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_linux.go
deleted file mode 100644
index 024187ff..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_linux.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// +build !cgo
-
-package term
-
-import (
- "syscall"
- "unsafe"
-)
-
-const (
- getTermios = syscall.TCGETS
- setTermios = syscall.TCSETS
-)
-
-type Termios struct {
- Iflag uint32
- Oflag uint32
- Cflag uint32
- Lflag uint32
- Cc [20]byte
- Ispeed uint32
- Ospeed uint32
-}
-
-// MakeRaw put the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd uintptr) (*State, error) {
- var oldState State
- if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
- return nil, err
- }
-
- newState := oldState.termios
-
- newState.Iflag &^= (syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON)
- newState.Oflag &^= syscall.OPOST
- newState.Lflag &^= (syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN)
- newState.Cflag &^= (syscall.CSIZE | syscall.PARENB)
- newState.Cflag |= syscall.CS8
-
- if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 {
- return nil, err
- }
- return &oldState, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/winconsole/console_windows.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/winconsole/console_windows.go
deleted file mode 100644
index ce40a931..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/winconsole/console_windows.go
+++ /dev/null
@@ -1,1053 +0,0 @@
-// +build windows
-
-package winconsole
-
-import (
- "bytes"
- "fmt"
- "io"
- "os"
- "strconv"
- "strings"
- "sync"
- "syscall"
- "unsafe"
-
- "github.com/Sirupsen/logrus"
-)
-
-const (
- // Consts for Get/SetConsoleMode function
- // -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
- ENABLE_PROCESSED_INPUT = 0x0001
- ENABLE_LINE_INPUT = 0x0002
- ENABLE_ECHO_INPUT = 0x0004
- ENABLE_WINDOW_INPUT = 0x0008
- ENABLE_MOUSE_INPUT = 0x0010
- ENABLE_INSERT_MODE = 0x0020
- ENABLE_QUICK_EDIT_MODE = 0x0040
- ENABLE_EXTENDED_FLAGS = 0x0080
-
- // If parameter is a screen buffer handle, additional values
- ENABLE_PROCESSED_OUTPUT = 0x0001
- ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002
-
- //http://msdn.microsoft.com/en-us/library/windows/desktop/ms682088(v=vs.85).aspx#_win32_character_attributes
- FOREGROUND_BLUE = 1
- FOREGROUND_GREEN = 2
- FOREGROUND_RED = 4
- FOREGROUND_INTENSITY = 8
- FOREGROUND_MASK_SET = 0x000F
- FOREGROUND_MASK_UNSET = 0xFFF0
-
- BACKGROUND_BLUE = 16
- BACKGROUND_GREEN = 32
- BACKGROUND_RED = 64
- BACKGROUND_INTENSITY = 128
- BACKGROUND_MASK_SET = 0x00F0
- BACKGROUND_MASK_UNSET = 0xFF0F
-
- COMMON_LVB_REVERSE_VIDEO = 0x4000
- COMMON_LVB_UNDERSCORE = 0x8000
-
- // http://man7.org/linux/man-pages/man4/console_codes.4.html
- // ECMA-48 Set Graphics Rendition
- ANSI_ATTR_RESET = 0
- ANSI_ATTR_BOLD = 1
- ANSI_ATTR_DIM = 2
- ANSI_ATTR_UNDERLINE = 4
- ANSI_ATTR_BLINK = 5
- ANSI_ATTR_REVERSE = 7
- ANSI_ATTR_INVISIBLE = 8
-
- ANSI_ATTR_UNDERLINE_OFF = 24
- ANSI_ATTR_BLINK_OFF = 25
- ANSI_ATTR_REVERSE_OFF = 27
- ANSI_ATTR_INVISIBLE_OFF = 8
-
- ANSI_FOREGROUND_BLACK = 30
- ANSI_FOREGROUND_RED = 31
- ANSI_FOREGROUND_GREEN = 32
- ANSI_FOREGROUND_YELLOW = 33
- ANSI_FOREGROUND_BLUE = 34
- ANSI_FOREGROUND_MAGENTA = 35
- ANSI_FOREGROUND_CYAN = 36
- ANSI_FOREGROUND_WHITE = 37
- ANSI_FOREGROUND_DEFAULT = 39
-
- ANSI_BACKGROUND_BLACK = 40
- ANSI_BACKGROUND_RED = 41
- ANSI_BACKGROUND_GREEN = 42
- ANSI_BACKGROUND_YELLOW = 43
- ANSI_BACKGROUND_BLUE = 44
- ANSI_BACKGROUND_MAGENTA = 45
- ANSI_BACKGROUND_CYAN = 46
- ANSI_BACKGROUND_WHITE = 47
- ANSI_BACKGROUND_DEFAULT = 49
-
- ANSI_MAX_CMD_LENGTH = 256
-
- MAX_INPUT_EVENTS = 128
- MAX_INPUT_BUFFER = 1024
- DEFAULT_WIDTH = 80
- DEFAULT_HEIGHT = 24
-)
-
-// http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
-const (
- VK_PRIOR = 0x21 // PAGE UP key
- VK_NEXT = 0x22 // PAGE DOWN key
- VK_END = 0x23 // END key
- VK_HOME = 0x24 // HOME key
- VK_LEFT = 0x25 // LEFT ARROW key
- VK_UP = 0x26 // UP ARROW key
- VK_RIGHT = 0x27 // RIGHT ARROW key
- VK_DOWN = 0x28 // DOWN ARROW key
- VK_SELECT = 0x29 // SELECT key
- VK_PRINT = 0x2A // PRINT key
- VK_EXECUTE = 0x2B // EXECUTE key
- VK_SNAPSHOT = 0x2C // PRINT SCREEN key
- VK_INSERT = 0x2D // INS key
- VK_DELETE = 0x2E // DEL key
- VK_HELP = 0x2F // HELP key
- VK_F1 = 0x70 // F1 key
- VK_F2 = 0x71 // F2 key
- VK_F3 = 0x72 // F3 key
- VK_F4 = 0x73 // F4 key
- VK_F5 = 0x74 // F5 key
- VK_F6 = 0x75 // F6 key
- VK_F7 = 0x76 // F7 key
- VK_F8 = 0x77 // F8 key
- VK_F9 = 0x78 // F9 key
- VK_F10 = 0x79 // F10 key
- VK_F11 = 0x7A // F11 key
- VK_F12 = 0x7B // F12 key
-)
-
-var kernel32DLL = syscall.NewLazyDLL("kernel32.dll")
-
-var (
- setConsoleModeProc = kernel32DLL.NewProc("SetConsoleMode")
- getConsoleScreenBufferInfoProc = kernel32DLL.NewProc("GetConsoleScreenBufferInfo")
- setConsoleCursorPositionProc = kernel32DLL.NewProc("SetConsoleCursorPosition")
- setConsoleTextAttributeProc = kernel32DLL.NewProc("SetConsoleTextAttribute")
- fillConsoleOutputCharacterProc = kernel32DLL.NewProc("FillConsoleOutputCharacterW")
- writeConsoleOutputProc = kernel32DLL.NewProc("WriteConsoleOutputW")
- readConsoleInputProc = kernel32DLL.NewProc("ReadConsoleInputW")
- getNumberOfConsoleInputEventsProc = kernel32DLL.NewProc("GetNumberOfConsoleInputEvents")
- getConsoleCursorInfoProc = kernel32DLL.NewProc("GetConsoleCursorInfo")
- setConsoleCursorInfoProc = kernel32DLL.NewProc("SetConsoleCursorInfo")
- setConsoleWindowInfoProc = kernel32DLL.NewProc("SetConsoleWindowInfo")
- setConsoleScreenBufferSizeProc = kernel32DLL.NewProc("SetConsoleScreenBufferSize")
-)
-
-// types for calling various windows API
-// see http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx
-type (
- SHORT int16
- BOOL int32
- WORD uint16
- WCHAR uint16
- DWORD uint32
-
- SMALL_RECT struct {
- Left SHORT
- Top SHORT
- Right SHORT
- Bottom SHORT
- }
-
- COORD struct {
- X SHORT
- Y SHORT
- }
-
- CONSOLE_SCREEN_BUFFER_INFO struct {
- Size COORD
- CursorPosition COORD
- Attributes WORD
- Window SMALL_RECT
- MaximumWindowSize COORD
- }
-
- CONSOLE_CURSOR_INFO struct {
- Size DWORD
- Visible BOOL
- }
-
- // http://msdn.microsoft.com/en-us/library/windows/desktop/ms684166(v=vs.85).aspx
- KEY_EVENT_RECORD struct {
- KeyDown BOOL
- RepeatCount WORD
- VirtualKeyCode WORD
- VirtualScanCode WORD
- UnicodeChar WCHAR
- ControlKeyState DWORD
- }
-
- INPUT_RECORD struct {
- EventType WORD
- KeyEvent KEY_EVENT_RECORD
- }
-
- CHAR_INFO struct {
- UnicodeChar WCHAR
- Attributes WORD
- }
-)
-
-// TODO(azlinux): Basic type clean-up
-// -- Convert all uses of uintptr to syscall.Handle to be consistent with Windows syscall
-// -- Convert, as appropriate, types to use defined Windows types (e.g., DWORD instead of uint32)
-
-// Implements the TerminalEmulator interface
-type WindowsTerminal struct {
- outMutex sync.Mutex
- inMutex sync.Mutex
- inputBuffer []byte
- inputSize int
- inputEvents []INPUT_RECORD
- screenBufferInfo *CONSOLE_SCREEN_BUFFER_INFO
- inputEscapeSequence []byte
-}
-
-func getStdHandle(stdhandle int) uintptr {
- handle, err := syscall.GetStdHandle(stdhandle)
- if err != nil {
- panic(fmt.Errorf("could not get standard io handle %d", stdhandle))
- }
- return uintptr(handle)
-}
-
-func WinConsoleStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
- handler := &WindowsTerminal{
- inputBuffer: make([]byte, MAX_INPUT_BUFFER),
- inputEscapeSequence: []byte(KEY_ESC_CSI),
- inputEvents: make([]INPUT_RECORD, MAX_INPUT_EVENTS),
- }
-
- if IsConsole(os.Stdin.Fd()) {
- stdIn = &terminalReader{
- wrappedReader: os.Stdin,
- emulator: handler,
- command: make([]byte, 0, ANSI_MAX_CMD_LENGTH),
- fd: getStdHandle(syscall.STD_INPUT_HANDLE),
- }
- } else {
- stdIn = os.Stdin
- }
-
- if IsConsole(os.Stdout.Fd()) {
- stdoutHandle := getStdHandle(syscall.STD_OUTPUT_HANDLE)
-
- // Save current screen buffer info
- screenBufferInfo, err := GetConsoleScreenBufferInfo(stdoutHandle)
- if err != nil {
- // If GetConsoleScreenBufferInfo returns a nil error, it usually means that stdout is not a TTY.
- // However, this is in the branch where stdout is a TTY, hence the panic.
- panic("could not get console screen buffer info")
- }
- handler.screenBufferInfo = screenBufferInfo
-
- buffer = make([]CHAR_INFO, screenBufferInfo.MaximumWindowSize.X*screenBufferInfo.MaximumWindowSize.Y)
-
- stdOut = &terminalWriter{
- wrappedWriter: os.Stdout,
- emulator: handler,
- command: make([]byte, 0, ANSI_MAX_CMD_LENGTH),
- fd: stdoutHandle,
- }
- } else {
- stdOut = os.Stdout
- }
-
- if IsConsole(os.Stderr.Fd()) {
- stdErr = &terminalWriter{
- wrappedWriter: os.Stderr,
- emulator: handler,
- command: make([]byte, 0, ANSI_MAX_CMD_LENGTH),
- fd: getStdHandle(syscall.STD_ERROR_HANDLE),
- }
- } else {
- stdErr = os.Stderr
- }
-
- return stdIn, stdOut, stdErr
-}
-
-// GetHandleInfo returns file descriptor and bool indicating whether the file is a console.
-func GetHandleInfo(in interface{}) (uintptr, bool) {
- var inFd uintptr
- var isTerminalIn bool
-
- switch t := in.(type) {
- case *terminalReader:
- in = t.wrappedReader
- case *terminalWriter:
- in = t.wrappedWriter
- }
-
- if file, ok := in.(*os.File); ok {
- inFd = file.Fd()
- isTerminalIn = IsConsole(inFd)
- }
- return inFd, isTerminalIn
-}
-
-func getError(r1, r2 uintptr, lastErr error) error {
- // If the function fails, the return value is zero.
- if r1 == 0 {
- if lastErr != nil {
- return lastErr
- }
- return syscall.EINVAL
- }
- return nil
-}
-
-// GetConsoleMode gets the console mode for given file descriptor
-// http://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx
-func GetConsoleMode(handle uintptr) (uint32, error) {
- var mode uint32
- err := syscall.GetConsoleMode(syscall.Handle(handle), &mode)
- return mode, err
-}
-
-// SetConsoleMode sets the console mode for given file descriptor
-// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
-func SetConsoleMode(handle uintptr, mode uint32) error {
- return getError(setConsoleModeProc.Call(handle, uintptr(mode), 0))
-}
-
-// SetCursorVisible sets the cursor visbility
-// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686019(v=vs.85).aspx
-func SetCursorVisible(handle uintptr, isVisible BOOL) (bool, error) {
- var cursorInfo *CONSOLE_CURSOR_INFO = &CONSOLE_CURSOR_INFO{}
- if err := getError(getConsoleCursorInfoProc.Call(handle, uintptr(unsafe.Pointer(cursorInfo)), 0)); err != nil {
- return false, err
- }
- cursorInfo.Visible = isVisible
- if err := getError(setConsoleCursorInfoProc.Call(handle, uintptr(unsafe.Pointer(cursorInfo)), 0)); err != nil {
- return false, err
- }
- return true, nil
-}
-
-// SetWindowSize sets the size of the console window.
-func SetWindowSize(handle uintptr, width, height, max SHORT) (bool, error) {
- window := SMALL_RECT{Left: 0, Top: 0, Right: width - 1, Bottom: height - 1}
- coord := COORD{X: width - 1, Y: max}
- if err := getError(setConsoleWindowInfoProc.Call(handle, uintptr(1), uintptr(unsafe.Pointer(&window)))); err != nil {
- return false, err
- }
- if err := getError(setConsoleScreenBufferSizeProc.Call(handle, marshal(coord))); err != nil {
- return false, err
- }
- return true, nil
-}
-
-// GetConsoleScreenBufferInfo retrieves information about the specified console screen buffer.
-// http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx
-func GetConsoleScreenBufferInfo(handle uintptr) (*CONSOLE_SCREEN_BUFFER_INFO, error) {
- var info CONSOLE_SCREEN_BUFFER_INFO
- if err := getError(getConsoleScreenBufferInfoProc.Call(handle, uintptr(unsafe.Pointer(&info)), 0)); err != nil {
- return nil, err
- }
- return &info, nil
-}
-
-// setConsoleTextAttribute sets the attributes of characters written to the
-// console screen buffer by the WriteFile or WriteConsole function,
-// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686047(v=vs.85).aspx
-func setConsoleTextAttribute(handle uintptr, attribute WORD) error {
- return getError(setConsoleTextAttributeProc.Call(handle, uintptr(attribute), 0))
-}
-
-func writeConsoleOutput(handle uintptr, buffer []CHAR_INFO, bufferSize COORD, bufferCoord COORD, writeRegion *SMALL_RECT) (bool, error) {
- if err := getError(writeConsoleOutputProc.Call(handle, uintptr(unsafe.Pointer(&buffer[0])), marshal(bufferSize), marshal(bufferCoord), uintptr(unsafe.Pointer(writeRegion)))); err != nil {
- return false, err
- }
- return true, nil
-}
-
-// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682663(v=vs.85).aspx
-func fillConsoleOutputCharacter(handle uintptr, fillChar byte, length uint32, writeCord COORD) (bool, error) {
- out := int64(0)
- if err := getError(fillConsoleOutputCharacterProc.Call(handle, uintptr(fillChar), uintptr(length), marshal(writeCord), uintptr(unsafe.Pointer(&out)))); err != nil {
- return false, err
- }
- return true, nil
-}
-
-// Gets the number of space characters to write for "clearing" the section of terminal
-func getNumberOfChars(fromCoord COORD, toCoord COORD, screenSize COORD) uint32 {
- // must be valid cursor position
- if fromCoord.X < 0 || fromCoord.Y < 0 || toCoord.X < 0 || toCoord.Y < 0 {
- return 0
- }
- if fromCoord.X >= screenSize.X || fromCoord.Y >= screenSize.Y || toCoord.X >= screenSize.X || toCoord.Y >= screenSize.Y {
- return 0
- }
- // can't be backwards
- if fromCoord.Y > toCoord.Y {
- return 0
- }
- // same line
- if fromCoord.Y == toCoord.Y {
- return uint32(toCoord.X-fromCoord.X) + 1
- }
- // spans more than one line
- if fromCoord.Y < toCoord.Y {
- // from start till end of line for first line + from start of line till end
- retValue := uint32(screenSize.X-fromCoord.X) + uint32(toCoord.X) + 1
- // don't count first and last line
- linesBetween := toCoord.Y - fromCoord.Y - 1
- if linesBetween > 0 {
- retValue = retValue + uint32(linesBetween*screenSize.X)
- }
- return retValue
- }
- return 0
-}
-
-var buffer []CHAR_INFO
-
-func clearDisplayRect(handle uintptr, attributes WORD, fromCoord COORD, toCoord COORD) (uint32, error) {
- var writeRegion SMALL_RECT
- writeRegion.Left = fromCoord.X
- writeRegion.Top = fromCoord.Y
- writeRegion.Right = toCoord.X
- writeRegion.Bottom = toCoord.Y
-
- // allocate and initialize buffer
- width := toCoord.X - fromCoord.X + 1
- height := toCoord.Y - fromCoord.Y + 1
- size := uint32(width) * uint32(height)
- if size > 0 {
- buffer := make([]CHAR_INFO, size)
- for i := range buffer {
- buffer[i] = CHAR_INFO{WCHAR(' '), attributes}
- }
-
- // Write to buffer
- r, err := writeConsoleOutput(handle, buffer, COORD{X: width, Y: height}, COORD{X: 0, Y: 0}, &writeRegion)
- if !r {
- if err != nil {
- return 0, err
- }
- return 0, syscall.EINVAL
- }
- }
- return uint32(size), nil
-}
-
-func clearDisplayRange(handle uintptr, attributes WORD, fromCoord COORD, toCoord COORD) (uint32, error) {
- nw := uint32(0)
- // start and end on same line
- if fromCoord.Y == toCoord.Y {
- return clearDisplayRect(handle, attributes, fromCoord, toCoord)
- }
- // TODO(azlinux): if full screen, optimize
-
- // spans more than one line
- if fromCoord.Y < toCoord.Y {
- // from start position till end of line for first line
- n, err := clearDisplayRect(handle, attributes, fromCoord, COORD{X: toCoord.X, Y: fromCoord.Y})
- if err != nil {
- return nw, err
- }
- nw += n
- // lines between
- linesBetween := toCoord.Y - fromCoord.Y - 1
- if linesBetween > 0 {
- n, err = clearDisplayRect(handle, attributes, COORD{X: 0, Y: fromCoord.Y + 1}, COORD{X: toCoord.X, Y: toCoord.Y - 1})
- if err != nil {
- return nw, err
- }
- nw += n
- }
- // lines at end
- n, err = clearDisplayRect(handle, attributes, COORD{X: 0, Y: toCoord.Y}, toCoord)
- if err != nil {
- return nw, err
- }
- nw += n
- }
- return nw, nil
-}
-
-// setConsoleCursorPosition sets the console cursor position
-// Note The X and Y are zero based
-// If relative is true then the new position is relative to current one
-func setConsoleCursorPosition(handle uintptr, isRelative bool, column int16, line int16) error {
- screenBufferInfo, err := GetConsoleScreenBufferInfo(handle)
- if err != nil {
- return err
- }
- var position COORD
- if isRelative {
- position.X = screenBufferInfo.CursorPosition.X + SHORT(column)
- position.Y = screenBufferInfo.CursorPosition.Y + SHORT(line)
- } else {
- position.X = SHORT(column)
- position.Y = SHORT(line)
- }
- return getError(setConsoleCursorPositionProc.Call(handle, marshal(position), 0))
-}
-
-// http://msdn.microsoft.com/en-us/library/windows/desktop/ms683207(v=vs.85).aspx
-func getNumberOfConsoleInputEvents(handle uintptr) (uint16, error) {
- var n DWORD
- if err := getError(getNumberOfConsoleInputEventsProc.Call(handle, uintptr(unsafe.Pointer(&n)))); err != nil {
- return 0, err
- }
- return uint16(n), nil
-}
-
-//http://msdn.microsoft.com/en-us/library/windows/desktop/ms684961(v=vs.85).aspx
-func readConsoleInputKey(handle uintptr, inputBuffer []INPUT_RECORD) (int, error) {
- var nr DWORD
- if err := getError(readConsoleInputProc.Call(handle, uintptr(unsafe.Pointer(&inputBuffer[0])), uintptr(len(inputBuffer)), uintptr(unsafe.Pointer(&nr)))); err != nil {
- return 0, err
- }
- return int(nr), nil
-}
-
-func getWindowsTextAttributeForAnsiValue(originalFlag WORD, defaultValue WORD, ansiValue int16) (WORD, error) {
- flag := WORD(originalFlag)
- if flag == 0 {
- flag = defaultValue
- }
- switch ansiValue {
- case ANSI_ATTR_RESET:
- flag &^= COMMON_LVB_UNDERSCORE
- flag &^= BACKGROUND_INTENSITY
- flag = flag | FOREGROUND_INTENSITY
- case ANSI_ATTR_INVISIBLE:
- // TODO: how do you reset reverse?
- case ANSI_ATTR_UNDERLINE:
- flag = flag | COMMON_LVB_UNDERSCORE
- case ANSI_ATTR_BLINK:
- // seems like background intenisty is blink
- flag = flag | BACKGROUND_INTENSITY
- case ANSI_ATTR_UNDERLINE_OFF:
- flag &^= COMMON_LVB_UNDERSCORE
- case ANSI_ATTR_BLINK_OFF:
- // seems like background intenisty is blink
- flag &^= BACKGROUND_INTENSITY
- case ANSI_ATTR_BOLD:
- flag = flag | FOREGROUND_INTENSITY
- case ANSI_ATTR_DIM:
- flag &^= FOREGROUND_INTENSITY
- case ANSI_ATTR_REVERSE, ANSI_ATTR_REVERSE_OFF:
- // swap forground and background bits
- foreground := flag & FOREGROUND_MASK_SET
- background := flag & BACKGROUND_MASK_SET
- flag = (flag & BACKGROUND_MASK_UNSET & FOREGROUND_MASK_UNSET) | (foreground << 4) | (background >> 4)
-
- // FOREGROUND
- case ANSI_FOREGROUND_DEFAULT:
- flag = (flag & FOREGROUND_MASK_UNSET) | (defaultValue & FOREGROUND_MASK_SET)
- case ANSI_FOREGROUND_BLACK:
- flag = flag ^ (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
- case ANSI_FOREGROUND_RED:
- flag = (flag & FOREGROUND_MASK_UNSET) | FOREGROUND_RED
- case ANSI_FOREGROUND_GREEN:
- flag = (flag & FOREGROUND_MASK_UNSET) | FOREGROUND_GREEN
- case ANSI_FOREGROUND_YELLOW:
- flag = (flag & FOREGROUND_MASK_UNSET) | FOREGROUND_RED | FOREGROUND_GREEN
- case ANSI_FOREGROUND_BLUE:
- flag = (flag & FOREGROUND_MASK_UNSET) | FOREGROUND_BLUE
- case ANSI_FOREGROUND_MAGENTA:
- flag = (flag & FOREGROUND_MASK_UNSET) | FOREGROUND_RED | FOREGROUND_BLUE
- case ANSI_FOREGROUND_CYAN:
- flag = (flag & FOREGROUND_MASK_UNSET) | FOREGROUND_GREEN | FOREGROUND_BLUE
- case ANSI_FOREGROUND_WHITE:
- flag = (flag & FOREGROUND_MASK_UNSET) | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
-
- // Background
- case ANSI_BACKGROUND_DEFAULT:
- // Black with no intensity
- flag = (flag & BACKGROUND_MASK_UNSET) | (defaultValue & BACKGROUND_MASK_SET)
- case ANSI_BACKGROUND_BLACK:
- flag = (flag & BACKGROUND_MASK_UNSET)
- case ANSI_BACKGROUND_RED:
- flag = (flag & BACKGROUND_MASK_UNSET) | BACKGROUND_RED
- case ANSI_BACKGROUND_GREEN:
- flag = (flag & BACKGROUND_MASK_UNSET) | BACKGROUND_GREEN
- case ANSI_BACKGROUND_YELLOW:
- flag = (flag & BACKGROUND_MASK_UNSET) | BACKGROUND_RED | BACKGROUND_GREEN
- case ANSI_BACKGROUND_BLUE:
- flag = (flag & BACKGROUND_MASK_UNSET) | BACKGROUND_BLUE
- case ANSI_BACKGROUND_MAGENTA:
- flag = (flag & BACKGROUND_MASK_UNSET) | BACKGROUND_RED | BACKGROUND_BLUE
- case ANSI_BACKGROUND_CYAN:
- flag = (flag & BACKGROUND_MASK_UNSET) | BACKGROUND_GREEN | BACKGROUND_BLUE
- case ANSI_BACKGROUND_WHITE:
- flag = (flag & BACKGROUND_MASK_UNSET) | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
- }
- return flag, nil
-}
-
-// HandleOutputCommand interpretes the Ansi commands and then makes appropriate Win32 calls
-func (term *WindowsTerminal) HandleOutputCommand(handle uintptr, command []byte) (n int, err error) {
- // always consider all the bytes in command, processed
- n = len(command)
-
- parsedCommand := parseAnsiCommand(command)
- logrus.Debugf("[windows] HandleOutputCommand: %v", parsedCommand)
-
- // console settings changes need to happen in atomic way
- term.outMutex.Lock()
- defer term.outMutex.Unlock()
-
- switch parsedCommand.Command {
- case "m":
- // [Value;...;Valuem
- // Set Graphics Mode:
- // Calls the graphics functions specified by the following values.
- // These specified functions remain active until the next occurrence of this escape sequence.
- // Graphics mode changes the colors and attributes of text (such as bold and underline) displayed on the screen.
- screenBufferInfo, err := GetConsoleScreenBufferInfo(handle)
- if err != nil {
- return n, err
- }
- flag := screenBufferInfo.Attributes
- for _, e := range parsedCommand.Parameters {
- value, _ := strconv.ParseInt(e, 10, 16) // base 10, 16 bit
- if value == ANSI_ATTR_RESET {
- flag = term.screenBufferInfo.Attributes // reset
- } else {
- flag, err = getWindowsTextAttributeForAnsiValue(flag, term.screenBufferInfo.Attributes, int16(value))
- if err != nil {
- return n, err
- }
- }
- }
- if err := setConsoleTextAttribute(handle, flag); err != nil {
- return n, err
- }
- case "H", "f":
- // [line;columnH
- // [line;columnf
- // Moves the cursor to the specified position (coordinates).
- // If you do not specify a position, the cursor moves to the home position at the upper-left corner of the screen (line 0, column 0).
- screenBufferInfo, err := GetConsoleScreenBufferInfo(handle)
- if err != nil {
- return n, err
- }
- line, err := parseInt16OrDefault(parsedCommand.getParam(0), 1)
- if err != nil {
- return n, err
- }
- if line > int16(screenBufferInfo.Window.Bottom) {
- line = int16(screenBufferInfo.Window.Bottom) + 1
- }
- column, err := parseInt16OrDefault(parsedCommand.getParam(1), 1)
- if err != nil {
- return n, err
- }
- if column > int16(screenBufferInfo.Window.Right) {
- column = int16(screenBufferInfo.Window.Right) + 1
- }
- // The numbers are not 0 based, but 1 based
- logrus.Debugf("[windows] HandleOutputCommmand: Moving cursor to (%v,%v)", column-1, line-1)
- if err := setConsoleCursorPosition(handle, false, column-1, line-1); err != nil {
- return n, err
- }
-
- case "A":
- // [valueA
- // Moves the cursor up by the specified number of lines without changing columns.
- // If the cursor is already on the top line, ignores this sequence.
- value, err := parseInt16OrDefault(parsedCommand.getParam(0), 1)
- if err != nil {
- return len(command), err
- }
- if err := setConsoleCursorPosition(handle, true, 0, -value); err != nil {
- return n, err
- }
- case "B":
- // [valueB
- // Moves the cursor down by the specified number of lines without changing columns.
- // If the cursor is already on the bottom line, ignores this sequence.
- value, err := parseInt16OrDefault(parsedCommand.getParam(0), 1)
- if err != nil {
- return n, err
- }
- if err := setConsoleCursorPosition(handle, true, 0, value); err != nil {
- return n, err
- }
- case "C":
- // [valueC
- // Moves the cursor forward by the specified number of columns without changing lines.
- // If the cursor is already in the rightmost column, ignores this sequence.
- value, err := parseInt16OrDefault(parsedCommand.getParam(0), 1)
- if err != nil {
- return n, err
- }
- if err := setConsoleCursorPosition(handle, true, value, 0); err != nil {
- return n, err
- }
- case "D":
- // [valueD
- // Moves the cursor back by the specified number of columns without changing lines.
- // If the cursor is already in the leftmost column, ignores this sequence.
- value, err := parseInt16OrDefault(parsedCommand.getParam(0), 1)
- if err != nil {
- return n, err
- }
- if err := setConsoleCursorPosition(handle, true, -value, 0); err != nil {
- return n, err
- }
- case "J":
- // [J Erases from the cursor to the end of the screen, including the cursor position.
- // [1J Erases from the beginning of the screen to the cursor, including the cursor position.
- // [2J Erases the complete display. The cursor does not move.
- // Clears the screen and moves the cursor to the home position (line 0, column 0).
- value, err := parseInt16OrDefault(parsedCommand.getParam(0), 0)
- if err != nil {
- return n, err
- }
- var start COORD
- var cursor COORD
- var end COORD
- screenBufferInfo, err := GetConsoleScreenBufferInfo(handle)
- if err != nil {
- return n, err
- }
- switch value {
- case 0:
- start = screenBufferInfo.CursorPosition
- // end of the buffer
- end.X = screenBufferInfo.Size.X - 1
- end.Y = screenBufferInfo.Size.Y - 1
- // cursor
- cursor = screenBufferInfo.CursorPosition
- case 1:
-
- // start of the screen
- start.X = 0
- start.Y = 0
- // end of the screen
- end = screenBufferInfo.CursorPosition
- // cursor
- cursor = screenBufferInfo.CursorPosition
- case 2:
- // start of the screen
- start.X = 0
- start.Y = 0
- // end of the buffer
- end.X = screenBufferInfo.Size.X - 1
- end.Y = screenBufferInfo.Size.Y - 1
- // cursor
- cursor.X = 0
- cursor.Y = 0
- }
- if _, err := clearDisplayRange(uintptr(handle), term.screenBufferInfo.Attributes, start, end); err != nil {
- return n, err
- }
- // remember the the cursor position is 1 based
- if err := setConsoleCursorPosition(handle, false, int16(cursor.X), int16(cursor.Y)); err != nil {
- return n, err
- }
-
- case "K":
- // [K
- // Clears all characters from the cursor position to the end of the line (including the character at the cursor position).
- // [K Erases from the cursor to the end of the line, including the cursor position.
- // [1K Erases from the beginning of the line to the cursor, including the cursor position.
- // [2K Erases the complete line.
- value, err := parseInt16OrDefault(parsedCommand.getParam(0), 0)
- var start COORD
- var cursor COORD
- var end COORD
- screenBufferInfo, err := GetConsoleScreenBufferInfo(uintptr(handle))
- if err != nil {
- return n, err
- }
- switch value {
- case 0:
- // start is where cursor is
- start = screenBufferInfo.CursorPosition
- // end of line
- end.X = screenBufferInfo.Size.X - 1
- end.Y = screenBufferInfo.CursorPosition.Y
- // cursor remains the same
- cursor = screenBufferInfo.CursorPosition
-
- case 1:
- // beginning of line
- start.X = 0
- start.Y = screenBufferInfo.CursorPosition.Y
- // until cursor
- end = screenBufferInfo.CursorPosition
- // cursor remains the same
- cursor = screenBufferInfo.CursorPosition
- case 2:
- // start of the line
- start.X = 0
- start.Y = screenBufferInfo.CursorPosition.Y - 1
- // end of the line
- end.X = screenBufferInfo.Size.X - 1
- end.Y = screenBufferInfo.CursorPosition.Y - 1
- // cursor
- cursor.X = 0
- cursor.Y = screenBufferInfo.CursorPosition.Y - 1
- }
- if _, err := clearDisplayRange(uintptr(handle), term.screenBufferInfo.Attributes, start, end); err != nil {
- return n, err
- }
- // remember the the cursor position is 1 based
- if err := setConsoleCursorPosition(uintptr(handle), false, int16(cursor.X), int16(cursor.Y)); err != nil {
- return n, err
- }
-
- case "l":
- for _, value := range parsedCommand.Parameters {
- switch value {
- case "?25", "25":
- SetCursorVisible(uintptr(handle), BOOL(0))
- case "?1049", "1049":
- // TODO (azlinux): Restore terminal
- case "?1", "1":
- // If the DECCKM function is reset, then the arrow keys send ANSI cursor sequences to the host.
- term.inputEscapeSequence = []byte(KEY_ESC_CSI)
- }
- }
- case "h":
- for _, value := range parsedCommand.Parameters {
- switch value {
- case "?25", "25":
- SetCursorVisible(uintptr(handle), BOOL(1))
- case "?1049", "1049":
- // TODO (azlinux): Save terminal
- case "?1", "1":
- // If the DECCKM function is set, then the arrow keys send application sequences to the host.
- // DECCKM (default off): When set, the cursor keys send an ESC O prefix, rather than ESC [.
- term.inputEscapeSequence = []byte(KEY_ESC_O)
- }
- }
-
- case "]":
- /*
- TODO (azlinux):
- Linux Console Private CSI Sequences
-
- The following sequences are neither ECMA-48 nor native VT102. They are
- native to the Linux console driver. Colors are in SGR parameters: 0 =
- black, 1 = red, 2 = green, 3 = brown, 4 = blue, 5 = magenta, 6 = cyan,
- 7 = white.
-
- ESC [ 1 ; n ] Set color n as the underline color
- ESC [ 2 ; n ] Set color n as the dim color
- ESC [ 8 ] Make the current color pair the default attributes.
- ESC [ 9 ; n ] Set screen blank timeout to n minutes.
- ESC [ 10 ; n ] Set bell frequency in Hz.
- ESC [ 11 ; n ] Set bell duration in msec.
- ESC [ 12 ; n ] Bring specified console to the front.
- ESC [ 13 ] Unblank the screen.
- ESC [ 14 ; n ] Set the VESA powerdown interval in minutes.
-
- */
- }
- return n, nil
-}
-
-// WriteChars writes the bytes to given writer.
-func (term *WindowsTerminal) WriteChars(fd uintptr, w io.Writer, p []byte) (n int, err error) {
- if len(p) == 0 {
- return 0, nil
- }
- return w.Write(p)
-}
-
-const (
- CAPSLOCK_ON = 0x0080 //The CAPS LOCK light is on.
- ENHANCED_KEY = 0x0100 //The key is enhanced.
- LEFT_ALT_PRESSED = 0x0002 //The left ALT key is pressed.
- LEFT_CTRL_PRESSED = 0x0008 //The left CTRL key is pressed.
- NUMLOCK_ON = 0x0020 //The NUM LOCK light is on.
- RIGHT_ALT_PRESSED = 0x0001 //The right ALT key is pressed.
- RIGHT_CTRL_PRESSED = 0x0004 //The right CTRL key is pressed.
- SCROLLLOCK_ON = 0x0040 //The SCROLL LOCK light is on.
- SHIFT_PRESSED = 0x0010 // The SHIFT key is pressed.
-)
-
-const (
- KEY_CONTROL_PARAM_2 = ";2"
- KEY_CONTROL_PARAM_3 = ";3"
- KEY_CONTROL_PARAM_4 = ";4"
- KEY_CONTROL_PARAM_5 = ";5"
- KEY_CONTROL_PARAM_6 = ";6"
- KEY_CONTROL_PARAM_7 = ";7"
- KEY_CONTROL_PARAM_8 = ";8"
- KEY_ESC_CSI = "\x1B["
- KEY_ESC_N = "\x1BN"
- KEY_ESC_O = "\x1BO"
-)
-
-var keyMapPrefix = map[WORD]string{
- VK_UP: "\x1B[%sA",
- VK_DOWN: "\x1B[%sB",
- VK_RIGHT: "\x1B[%sC",
- VK_LEFT: "\x1B[%sD",
- VK_HOME: "\x1B[1%s~", // showkey shows ^[[1
- VK_END: "\x1B[4%s~", // showkey shows ^[[4
- VK_INSERT: "\x1B[2%s~",
- VK_DELETE: "\x1B[3%s~",
- VK_PRIOR: "\x1B[5%s~",
- VK_NEXT: "\x1B[6%s~",
- VK_F1: "",
- VK_F2: "",
- VK_F3: "\x1B[13%s~",
- VK_F4: "\x1B[14%s~",
- VK_F5: "\x1B[15%s~",
- VK_F6: "\x1B[17%s~",
- VK_F7: "\x1B[18%s~",
- VK_F8: "\x1B[19%s~",
- VK_F9: "\x1B[20%s~",
- VK_F10: "\x1B[21%s~",
- VK_F11: "\x1B[23%s~",
- VK_F12: "\x1B[24%s~",
-}
-
-var arrowKeyMapPrefix = map[WORD]string{
- VK_UP: "%s%sA",
- VK_DOWN: "%s%sB",
- VK_RIGHT: "%s%sC",
- VK_LEFT: "%s%sD",
-}
-
-func getControlStateParameter(shift, alt, control, meta bool) string {
- if shift && alt && control {
- return KEY_CONTROL_PARAM_8
- }
- if alt && control {
- return KEY_CONTROL_PARAM_7
- }
- if shift && control {
- return KEY_CONTROL_PARAM_6
- }
- if control {
- return KEY_CONTROL_PARAM_5
- }
- if shift && alt {
- return KEY_CONTROL_PARAM_4
- }
- if alt {
- return KEY_CONTROL_PARAM_3
- }
- if shift {
- return KEY_CONTROL_PARAM_2
- }
- return ""
-}
-
-func getControlKeys(controlState DWORD) (shift, alt, control bool) {
- shift = 0 != (controlState & SHIFT_PRESSED)
- alt = 0 != (controlState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
- control = 0 != (controlState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
- return shift, alt, control
-}
-
-func charSequenceForKeys(key WORD, controlState DWORD, escapeSequence []byte) string {
- i, ok := arrowKeyMapPrefix[key]
- if ok {
- shift, alt, control := getControlKeys(controlState)
- modifier := getControlStateParameter(shift, alt, control, false)
- return fmt.Sprintf(i, escapeSequence, modifier)
- }
-
- i, ok = keyMapPrefix[key]
- if ok {
- shift, alt, control := getControlKeys(controlState)
- modifier := getControlStateParameter(shift, alt, control, false)
- return fmt.Sprintf(i, modifier)
- }
-
- return ""
-}
-
-// mapKeystokeToTerminalString maps the given input event record to string
-func mapKeystokeToTerminalString(keyEvent *KEY_EVENT_RECORD, escapeSequence []byte) string {
- _, alt, control := getControlKeys(keyEvent.ControlKeyState)
- if keyEvent.UnicodeChar == 0 {
- return charSequenceForKeys(keyEvent.VirtualKeyCode, keyEvent.ControlKeyState, escapeSequence)
- }
- if control {
- // TODO(azlinux): Implement following control sequences
- // -D Signals the end of input from the keyboard; also exits current shell.
- // -H Deletes the first character to the left of the cursor. Also called the ERASE key.
- // -Q Restarts printing after it has been stopped with -s.
- // -S Suspends printing on the screen (does not stop the program).
- // -U Deletes all characters on the current line. Also called the KILL key.
- // -E Quits current command and creates a core
-
- }
- // +Key generates ESC N Key
- if !control && alt {
- return KEY_ESC_N + strings.ToLower(string(keyEvent.UnicodeChar))
- }
- return string(keyEvent.UnicodeChar)
-}
-
-// getAvailableInputEvents polls the console for availble events
-// The function does not return until at least one input record has been read.
-func getAvailableInputEvents(handle uintptr, inputEvents []INPUT_RECORD) (n int, err error) {
- // TODO(azlinux): Why is there a for loop? Seems to me, that `n` cannot be negative. - tibor
- for {
- // Read number of console events available
- n, err = readConsoleInputKey(handle, inputEvents)
- if err != nil || n >= 0 {
- return n, err
- }
- }
-}
-
-// getTranslatedKeyCodes converts the input events into the string of characters
-// The ansi escape sequence are used to map key strokes to the strings
-func getTranslatedKeyCodes(inputEvents []INPUT_RECORD, escapeSequence []byte) string {
- var buf bytes.Buffer
- for i := 0; i < len(inputEvents); i++ {
- input := inputEvents[i]
- if input.EventType == KEY_EVENT && input.KeyEvent.KeyDown != 0 {
- keyString := mapKeystokeToTerminalString(&input.KeyEvent, escapeSequence)
- buf.WriteString(keyString)
- }
- }
- return buf.String()
-}
-
-// ReadChars reads the characters from the given reader
-func (term *WindowsTerminal) ReadChars(fd uintptr, r io.Reader, p []byte) (n int, err error) {
- for term.inputSize == 0 {
- nr, err := getAvailableInputEvents(fd, term.inputEvents)
- if nr == 0 && nil != err {
- return n, err
- }
- if nr > 0 {
- keyCodes := getTranslatedKeyCodes(term.inputEvents[:nr], term.inputEscapeSequence)
- term.inputSize = copy(term.inputBuffer, keyCodes)
- }
- }
- n = copy(p, term.inputBuffer[:term.inputSize])
- term.inputSize -= n
- return n, nil
-}
-
-// HandleInputSequence interprets the input sequence command
-func (term *WindowsTerminal) HandleInputSequence(fd uintptr, command []byte) (n int, err error) {
- return 0, nil
-}
-
-func marshal(c COORD) uintptr {
- return uintptr(*((*DWORD)(unsafe.Pointer(&c))))
-}
-
-// IsConsole returns true if the given file descriptor is a terminal.
-// -- The code assumes that GetConsoleMode will return an error for file descriptors that are not a console.
-func IsConsole(fd uintptr) bool {
- _, e := GetConsoleMode(fd)
- return e == nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/winconsole/term_emulator.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/winconsole/term_emulator.go
deleted file mode 100644
index 2d5edc03..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/docker/pkg/term/winconsole/term_emulator.go
+++ /dev/null
@@ -1,234 +0,0 @@
-package winconsole
-
-import (
- "fmt"
- "io"
- "strconv"
- "strings"
-)
-
-// http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html
-const (
- ANSI_ESCAPE_PRIMARY = 0x1B
- ANSI_ESCAPE_SECONDARY = 0x5B
- ANSI_COMMAND_FIRST = 0x40
- ANSI_COMMAND_LAST = 0x7E
- ANSI_PARAMETER_SEP = ";"
- ANSI_CMD_G0 = '('
- ANSI_CMD_G1 = ')'
- ANSI_CMD_G2 = '*'
- ANSI_CMD_G3 = '+'
- ANSI_CMD_DECPNM = '>'
- ANSI_CMD_DECPAM = '='
- ANSI_CMD_OSC = ']'
- ANSI_CMD_STR_TERM = '\\'
- ANSI_BEL = 0x07
- KEY_EVENT = 1
-)
-
-// Interface that implements terminal handling
-type terminalEmulator interface {
- HandleOutputCommand(fd uintptr, command []byte) (n int, err error)
- HandleInputSequence(fd uintptr, command []byte) (n int, err error)
- WriteChars(fd uintptr, w io.Writer, p []byte) (n int, err error)
- ReadChars(fd uintptr, w io.Reader, p []byte) (n int, err error)
-}
-
-type terminalWriter struct {
- wrappedWriter io.Writer
- emulator terminalEmulator
- command []byte
- inSequence bool
- fd uintptr
-}
-
-type terminalReader struct {
- wrappedReader io.ReadCloser
- emulator terminalEmulator
- command []byte
- inSequence bool
- fd uintptr
-}
-
-// http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html
-func isAnsiCommandChar(b byte) bool {
- switch {
- case ANSI_COMMAND_FIRST <= b && b <= ANSI_COMMAND_LAST && b != ANSI_ESCAPE_SECONDARY:
- return true
- case b == ANSI_CMD_G1 || b == ANSI_CMD_OSC || b == ANSI_CMD_DECPAM || b == ANSI_CMD_DECPNM:
- // non-CSI escape sequence terminator
- return true
- case b == ANSI_CMD_STR_TERM || b == ANSI_BEL:
- // String escape sequence terminator
- return true
- }
- return false
-}
-
-func isCharacterSelectionCmdChar(b byte) bool {
- return (b == ANSI_CMD_G0 || b == ANSI_CMD_G1 || b == ANSI_CMD_G2 || b == ANSI_CMD_G3)
-}
-
-func isXtermOscSequence(command []byte, current byte) bool {
- return (len(command) >= 2 && command[0] == ANSI_ESCAPE_PRIMARY && command[1] == ANSI_CMD_OSC && current != ANSI_BEL)
-}
-
-// Write writes len(p) bytes from p to the underlying data stream.
-// http://golang.org/pkg/io/#Writer
-func (tw *terminalWriter) Write(p []byte) (n int, err error) {
- if len(p) == 0 {
- return 0, nil
- }
- if tw.emulator == nil {
- return tw.wrappedWriter.Write(p)
- }
- // Emulate terminal by extracting commands and executing them
- totalWritten := 0
- start := 0 // indicates start of the next chunk
- end := len(p)
- for current := 0; current < end; current++ {
- if tw.inSequence {
- // inside escape sequence
- tw.command = append(tw.command, p[current])
- if isAnsiCommandChar(p[current]) {
- if !isXtermOscSequence(tw.command, p[current]) {
- // found the last command character.
- // Now we have a complete command.
- nchar, err := tw.emulator.HandleOutputCommand(tw.fd, tw.command)
- totalWritten += nchar
- if err != nil {
- return totalWritten, err
- }
-
- // clear the command
- // don't include current character again
- tw.command = tw.command[:0]
- start = current + 1
- tw.inSequence = false
- }
- }
- } else {
- if p[current] == ANSI_ESCAPE_PRIMARY {
- // entering escape sequnce
- tw.inSequence = true
- // indicates end of "normal sequence", write whatever you have so far
- if len(p[start:current]) > 0 {
- nw, err := tw.emulator.WriteChars(tw.fd, tw.wrappedWriter, p[start:current])
- totalWritten += nw
- if err != nil {
- return totalWritten, err
- }
- }
- // include the current character as part of the next sequence
- tw.command = append(tw.command, p[current])
- }
- }
- }
- // note that so far, start of the escape sequence triggers writing out of bytes to console.
- // For the part _after_ the end of last escape sequence, it is not written out yet. So write it out
- if !tw.inSequence {
- // assumption is that we can't be inside sequence and therefore command should be empty
- if len(p[start:]) > 0 {
- nw, err := tw.emulator.WriteChars(tw.fd, tw.wrappedWriter, p[start:])
- totalWritten += nw
- if err != nil {
- return totalWritten, err
- }
- }
- }
- return totalWritten, nil
-
-}
-
-// Read reads up to len(p) bytes into p.
-// http://golang.org/pkg/io/#Reader
-func (tr *terminalReader) Read(p []byte) (n int, err error) {
- //Implementations of Read are discouraged from returning a zero byte count
- // with a nil error, except when len(p) == 0.
- if len(p) == 0 {
- return 0, nil
- }
- if nil == tr.emulator {
- return tr.readFromWrappedReader(p)
- }
- return tr.emulator.ReadChars(tr.fd, tr.wrappedReader, p)
-}
-
-// Close the underlying stream
-func (tr *terminalReader) Close() (err error) {
- return tr.wrappedReader.Close()
-}
-
-func (tr *terminalReader) readFromWrappedReader(p []byte) (n int, err error) {
- return tr.wrappedReader.Read(p)
-}
-
-type ansiCommand struct {
- CommandBytes []byte
- Command string
- Parameters []string
- IsSpecial bool
-}
-
-func parseAnsiCommand(command []byte) *ansiCommand {
- if isCharacterSelectionCmdChar(command[1]) {
- // Is Character Set Selection commands
- return &ansiCommand{
- CommandBytes: command,
- Command: string(command),
- IsSpecial: true,
- }
- }
- // last char is command character
- lastCharIndex := len(command) - 1
-
- retValue := &ansiCommand{
- CommandBytes: command,
- Command: string(command[lastCharIndex]),
- IsSpecial: false,
- }
- // more than a single escape
- if lastCharIndex != 0 {
- start := 1
- // skip if double char escape sequence
- if command[0] == ANSI_ESCAPE_PRIMARY && command[1] == ANSI_ESCAPE_SECONDARY {
- start++
- }
- // convert this to GetNextParam method
- retValue.Parameters = strings.Split(string(command[start:lastCharIndex]), ANSI_PARAMETER_SEP)
- }
- return retValue
-}
-
-func (c *ansiCommand) getParam(index int) string {
- if len(c.Parameters) > index {
- return c.Parameters[index]
- }
- return ""
-}
-
-func (ac *ansiCommand) String() string {
- return fmt.Sprintf("0x%v \"%v\" (\"%v\")",
- bytesToHex(ac.CommandBytes),
- ac.Command,
- strings.Join(ac.Parameters, "\",\""))
-}
-
-func bytesToHex(b []byte) string {
- hex := make([]string, len(b))
- for i, ch := range b {
- hex[i] = fmt.Sprintf("%X", ch)
- }
- return strings.Join(hex, "")
-}
-
-func parseInt16OrDefault(s string, defaultValue int16) (n int16, err error) {
- if s == "" {
- return defaultValue, nil
- }
- parsedValue, err := strconv.ParseInt(s, 10, 16)
- if err != nil {
- return defaultValue, err
- }
- return int16(parsedValue), nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/go-units/LICENSE b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/go-units/LICENSE
deleted file mode 100644
index b55b37bc..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/go-units/LICENSE
+++ /dev/null
@@ -1,191 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- https://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
-
- Copyright 2015 Docker, Inc.
-
- 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
-
- https://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/opencontainers/runc/Godeps/_workspace/src/github.com/docker/go-units/README.md b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/go-units/README.md
deleted file mode 100644
index f1d46d16..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/go-units/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# Introduction
-
-go-units is a library to transform human friendly measurements into machine friendly values.
-
-## Usage
-
-See the [docs in godoc](https://godoc.org/github.com/docker/go-units) for examples and documentation.
-
-## License
-
-go-units is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for the full license text.
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/go-units/duration.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/go-units/duration.go
deleted file mode 100644
index c219a8a9..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/go-units/duration.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Package units provides helper function to parse and print size and time units
-// in human-readable format.
-package units
-
-import (
- "fmt"
- "time"
-)
-
-// HumanDuration returns a human-readable approximation of a duration
-// (eg. "About a minute", "4 hours ago", etc.).
-func HumanDuration(d time.Duration) string {
- if seconds := int(d.Seconds()); seconds < 1 {
- return "Less than a second"
- } else if seconds < 60 {
- return fmt.Sprintf("%d seconds", seconds)
- } else if minutes := int(d.Minutes()); minutes == 1 {
- return "About a minute"
- } else if minutes < 60 {
- return fmt.Sprintf("%d minutes", minutes)
- } else if hours := int(d.Hours()); hours == 1 {
- return "About an hour"
- } else if hours < 48 {
- return fmt.Sprintf("%d hours", hours)
- } else if hours < 24*7*2 {
- return fmt.Sprintf("%d days", hours/24)
- } else if hours < 24*30*3 {
- return fmt.Sprintf("%d weeks", hours/24/7)
- } else if hours < 24*365*2 {
- return fmt.Sprintf("%d months", hours/24/30)
- }
- return fmt.Sprintf("%d years", int(d.Hours())/24/365)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/go-units/size.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/go-units/size.go
deleted file mode 100644
index 3b59daff..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/docker/go-units/size.go
+++ /dev/null
@@ -1,95 +0,0 @@
-package units
-
-import (
- "fmt"
- "regexp"
- "strconv"
- "strings"
-)
-
-// See: http://en.wikipedia.org/wiki/Binary_prefix
-const (
- // Decimal
-
- KB = 1000
- MB = 1000 * KB
- GB = 1000 * MB
- TB = 1000 * GB
- PB = 1000 * TB
-
- // Binary
-
- KiB = 1024
- MiB = 1024 * KiB
- GiB = 1024 * MiB
- TiB = 1024 * GiB
- PiB = 1024 * TiB
-)
-
-type unitMap map[string]int64
-
-var (
- decimalMap = unitMap{"k": KB, "m": MB, "g": GB, "t": TB, "p": PB}
- binaryMap = unitMap{"k": KiB, "m": MiB, "g": GiB, "t": TiB, "p": PiB}
- sizeRegex = regexp.MustCompile(`^(\d+)([kKmMgGtTpP])?[bB]?$`)
-)
-
-var decimapAbbrs = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
-var binaryAbbrs = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"}
-
-// CustomSize returns a human-readable approximation of a size
-// using custom format.
-func CustomSize(format string, size float64, base float64, _map []string) string {
- i := 0
- for size >= base {
- size = size / base
- i++
- }
- return fmt.Sprintf(format, size, _map[i])
-}
-
-// HumanSize returns a human-readable approximation of a size
-// capped at 4 valid numbers (eg. "2.746 MB", "796 KB").
-func HumanSize(size float64) string {
- return CustomSize("%.4g %s", size, 1000.0, decimapAbbrs)
-}
-
-// BytesSize returns a human-readable size in bytes, kibibytes,
-// mebibytes, gibibytes, or tebibytes (eg. "44kiB", "17MiB").
-func BytesSize(size float64) string {
- return CustomSize("%.4g %s", size, 1024.0, binaryAbbrs)
-}
-
-// FromHumanSize returns an integer from a human-readable specification of a
-// size using SI standard (eg. "44kB", "17MB").
-func FromHumanSize(size string) (int64, error) {
- return parseSize(size, decimalMap)
-}
-
-// RAMInBytes parses a human-readable string representing an amount of RAM
-// in bytes, kibibytes, mebibytes, gibibytes, or tebibytes and
-// returns the number of bytes, or -1 if the string is unparseable.
-// Units are case-insensitive, and the 'b' suffix is optional.
-func RAMInBytes(size string) (int64, error) {
- return parseSize(size, binaryMap)
-}
-
-// Parses the human-readable size string into the amount it represents.
-func parseSize(sizeStr string, uMap unitMap) (int64, error) {
- matches := sizeRegex.FindStringSubmatch(sizeStr)
- if len(matches) != 3 {
- return -1, fmt.Errorf("invalid size: '%s'", sizeStr)
- }
-
- size, err := strconv.ParseInt(matches[1], 10, 0)
- if err != nil {
- return -1, err
- }
-
- unitPrefix := strings.ToLower(matches[2])
- if mul, ok := uMap[unitPrefix]; ok {
- size *= mul
- }
-
- return size, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/CONTRIBUTING.md b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/CONTRIBUTING.md
deleted file mode 100644
index c88f9b2b..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/CONTRIBUTING.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# How to Contribute
-
-## Getting Started
-
-- Fork the repository on GitHub
-- Read the [README](README.markdown) for build and test instructions
-- Play with the project, submit bugs, submit patches!
-
-## Contribution Flow
-
-This is a rough outline of what a contributor's workflow looks like:
-
-- Create a topic branch from where you want to base your work (usually master).
-- Make commits of logical units.
-- Make sure your commit messages are in the proper format (see below).
-- Push your changes to a topic branch in your fork of the repository.
-- Make sure the tests pass, and add any new tests as appropriate.
-- Submit a pull request to the original repository.
-
-Thanks for your contributions!
-
-### Format of the Commit Message
-
-We follow a rough convention for commit messages that is designed to answer two
-questions: what changed and why. The subject line should feature the what and
-the body of the commit should describe the why.
-
-```
-scripts: add the test-cluster command
-
-this uses tmux to setup a test cluster that you can easily kill and
-start for debugging.
-
-Fixes #38
-```
-
-The format can be described more formally as follows:
-
-```
-:
-
-
-
-
-```
-
-The first line is the subject and should be no longer than 70 characters, the
-second line is always blank, and other lines should be wrapped at 80 characters.
-This allows the message to be easier to read on GitHub as well as in various
-git tools.
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/LICENSE b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/LICENSE
deleted file mode 100644
index 670d88fc..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2013, Georg Reinke (), Google
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/MAINTAINERS b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/MAINTAINERS
deleted file mode 100644
index e8968ece..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/MAINTAINERS
+++ /dev/null
@@ -1,2 +0,0 @@
-Brandon Philips (@philips)
-Brian Waldon (@bcwaldon)
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/README.markdown b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/README.markdown
deleted file mode 100644
index 0a6e7e5b..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/README.markdown
+++ /dev/null
@@ -1,41 +0,0 @@
-dbus
-----
-
-dbus is a simple library that implements native Go client bindings for the
-D-Bus message bus system.
-
-### Features
-
-* Complete native implementation of the D-Bus message protocol
-* Go-like API (channels for signals / asynchronous method calls, Goroutine-safe connections)
-* Subpackages that help with the introspection / property interfaces
-
-### Installation
-
-This packages requires Go 1.1. If you installed it and set up your GOPATH, just run:
-
-```
-go get github.com/godbus/dbus
-```
-
-If you want to use the subpackages, you can install them the same way.
-
-### Usage
-
-The complete package documentation and some simple examples are available at
-[godoc.org](http://godoc.org/github.com/godbus/dbus). Also, the
-[_examples](https://github.com/godbus/dbus/tree/master/_examples) directory
-gives a short overview over the basic usage.
-
-#### Projects using godbus
-- [notify](https://github.com/esiqveland/notify) provides desktop notifications over dbus into a library.
-
-Please note that the API is considered unstable for now and may change without
-further notice.
-
-### License
-
-go.dbus is available under the Simplified BSD License; see LICENSE for the full
-text.
-
-Nearly all of the credit for this library goes to github.com/guelfey/go.dbus.
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/auth.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/auth.go
deleted file mode 100644
index 98017b69..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/auth.go
+++ /dev/null
@@ -1,253 +0,0 @@
-package dbus
-
-import (
- "bufio"
- "bytes"
- "errors"
- "io"
- "os"
- "strconv"
-)
-
-// AuthStatus represents the Status of an authentication mechanism.
-type AuthStatus byte
-
-const (
- // AuthOk signals that authentication is finished; the next command
- // from the server should be an OK.
- AuthOk AuthStatus = iota
-
- // AuthContinue signals that additional data is needed; the next command
- // from the server should be a DATA.
- AuthContinue
-
- // AuthError signals an error; the server sent invalid data or some
- // other unexpected thing happened and the current authentication
- // process should be aborted.
- AuthError
-)
-
-type authState byte
-
-const (
- waitingForData authState = iota
- waitingForOk
- waitingForReject
-)
-
-// Auth defines the behaviour of an authentication mechanism.
-type Auth interface {
- // Return the name of the mechnism, the argument to the first AUTH command
- // and the next status.
- FirstData() (name, resp []byte, status AuthStatus)
-
- // Process the given DATA command, and return the argument to the DATA
- // command and the next status. If len(resp) == 0, no DATA command is sent.
- HandleData(data []byte) (resp []byte, status AuthStatus)
-}
-
-// Auth authenticates the connection, trying the given list of authentication
-// mechanisms (in that order). If nil is passed, the EXTERNAL and
-// DBUS_COOKIE_SHA1 mechanisms are tried for the current user. For private
-// connections, this method must be called before sending any messages to the
-// bus. Auth must not be called on shared connections.
-func (conn *Conn) Auth(methods []Auth) error {
- if methods == nil {
- uid := strconv.Itoa(os.Getuid())
- methods = []Auth{AuthExternal(uid), AuthCookieSha1(uid, getHomeDir())}
- }
- in := bufio.NewReader(conn.transport)
- err := conn.transport.SendNullByte()
- if err != nil {
- return err
- }
- err = authWriteLine(conn.transport, []byte("AUTH"))
- if err != nil {
- return err
- }
- s, err := authReadLine(in)
- if err != nil {
- return err
- }
- if len(s) < 2 || !bytes.Equal(s[0], []byte("REJECTED")) {
- return errors.New("dbus: authentication protocol error")
- }
- s = s[1:]
- for _, v := range s {
- for _, m := range methods {
- if name, data, status := m.FirstData(); bytes.Equal(v, name) {
- var ok bool
- err = authWriteLine(conn.transport, []byte("AUTH"), []byte(v), data)
- if err != nil {
- return err
- }
- switch status {
- case AuthOk:
- err, ok = conn.tryAuth(m, waitingForOk, in)
- case AuthContinue:
- err, ok = conn.tryAuth(m, waitingForData, in)
- default:
- panic("dbus: invalid authentication status")
- }
- if err != nil {
- return err
- }
- if ok {
- if conn.transport.SupportsUnixFDs() {
- err = authWriteLine(conn, []byte("NEGOTIATE_UNIX_FD"))
- if err != nil {
- return err
- }
- line, err := authReadLine(in)
- if err != nil {
- return err
- }
- switch {
- case bytes.Equal(line[0], []byte("AGREE_UNIX_FD")):
- conn.EnableUnixFDs()
- conn.unixFD = true
- case bytes.Equal(line[0], []byte("ERROR")):
- default:
- return errors.New("dbus: authentication protocol error")
- }
- }
- err = authWriteLine(conn.transport, []byte("BEGIN"))
- if err != nil {
- return err
- }
- go conn.inWorker()
- go conn.outWorker()
- return nil
- }
- }
- }
- }
- return errors.New("dbus: authentication failed")
-}
-
-// tryAuth tries to authenticate with m as the mechanism, using state as the
-// initial authState and in for reading input. It returns (nil, true) on
-// success, (nil, false) on a REJECTED and (someErr, false) if some other
-// error occured.
-func (conn *Conn) tryAuth(m Auth, state authState, in *bufio.Reader) (error, bool) {
- for {
- s, err := authReadLine(in)
- if err != nil {
- return err, false
- }
- switch {
- case state == waitingForData && string(s[0]) == "DATA":
- if len(s) != 2 {
- err = authWriteLine(conn.transport, []byte("ERROR"))
- if err != nil {
- return err, false
- }
- continue
- }
- data, status := m.HandleData(s[1])
- switch status {
- case AuthOk, AuthContinue:
- if len(data) != 0 {
- err = authWriteLine(conn.transport, []byte("DATA"), data)
- if err != nil {
- return err, false
- }
- }
- if status == AuthOk {
- state = waitingForOk
- }
- case AuthError:
- err = authWriteLine(conn.transport, []byte("ERROR"))
- if err != nil {
- return err, false
- }
- }
- case state == waitingForData && string(s[0]) == "REJECTED":
- return nil, false
- case state == waitingForData && string(s[0]) == "ERROR":
- err = authWriteLine(conn.transport, []byte("CANCEL"))
- if err != nil {
- return err, false
- }
- state = waitingForReject
- case state == waitingForData && string(s[0]) == "OK":
- if len(s) != 2 {
- err = authWriteLine(conn.transport, []byte("CANCEL"))
- if err != nil {
- return err, false
- }
- state = waitingForReject
- }
- conn.uuid = string(s[1])
- return nil, true
- case state == waitingForData:
- err = authWriteLine(conn.transport, []byte("ERROR"))
- if err != nil {
- return err, false
- }
- case state == waitingForOk && string(s[0]) == "OK":
- if len(s) != 2 {
- err = authWriteLine(conn.transport, []byte("CANCEL"))
- if err != nil {
- return err, false
- }
- state = waitingForReject
- }
- conn.uuid = string(s[1])
- return nil, true
- case state == waitingForOk && string(s[0]) == "REJECTED":
- return nil, false
- case state == waitingForOk && (string(s[0]) == "DATA" ||
- string(s[0]) == "ERROR"):
-
- err = authWriteLine(conn.transport, []byte("CANCEL"))
- if err != nil {
- return err, false
- }
- state = waitingForReject
- case state == waitingForOk:
- err = authWriteLine(conn.transport, []byte("ERROR"))
- if err != nil {
- return err, false
- }
- case state == waitingForReject && string(s[0]) == "REJECTED":
- return nil, false
- case state == waitingForReject:
- return errors.New("dbus: authentication protocol error"), false
- default:
- panic("dbus: invalid auth state")
- }
- }
-}
-
-// authReadLine reads a line and separates it into its fields.
-func authReadLine(in *bufio.Reader) ([][]byte, error) {
- data, err := in.ReadBytes('\n')
- if err != nil {
- return nil, err
- }
- data = bytes.TrimSuffix(data, []byte("\r\n"))
- return bytes.Split(data, []byte{' '}), nil
-}
-
-// authWriteLine writes the given line in the authentication protocol format
-// (elements of data separated by a " " and terminated by "\r\n").
-func authWriteLine(out io.Writer, data ...[]byte) error {
- buf := make([]byte, 0)
- for i, v := range data {
- buf = append(buf, v...)
- if i != len(data)-1 {
- buf = append(buf, ' ')
- }
- }
- buf = append(buf, '\r')
- buf = append(buf, '\n')
- n, err := out.Write(buf)
- if err != nil {
- return err
- }
- if n != len(buf) {
- return io.ErrUnexpectedEOF
- }
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/auth_external.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/auth_external.go
deleted file mode 100644
index 7e376d3e..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/auth_external.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package dbus
-
-import (
- "encoding/hex"
-)
-
-// AuthExternal returns an Auth that authenticates as the given user with the
-// EXTERNAL mechanism.
-func AuthExternal(user string) Auth {
- return authExternal{user}
-}
-
-// AuthExternal implements the EXTERNAL authentication mechanism.
-type authExternal struct {
- user string
-}
-
-func (a authExternal) FirstData() ([]byte, []byte, AuthStatus) {
- b := make([]byte, 2*len(a.user))
- hex.Encode(b, []byte(a.user))
- return []byte("EXTERNAL"), b, AuthOk
-}
-
-func (a authExternal) HandleData(b []byte) ([]byte, AuthStatus) {
- return nil, AuthError
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/auth_sha1.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/auth_sha1.go
deleted file mode 100644
index df15b461..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/auth_sha1.go
+++ /dev/null
@@ -1,102 +0,0 @@
-package dbus
-
-import (
- "bufio"
- "bytes"
- "crypto/rand"
- "crypto/sha1"
- "encoding/hex"
- "os"
-)
-
-// AuthCookieSha1 returns an Auth that authenticates as the given user with the
-// DBUS_COOKIE_SHA1 mechanism. The home parameter should specify the home
-// directory of the user.
-func AuthCookieSha1(user, home string) Auth {
- return authCookieSha1{user, home}
-}
-
-type authCookieSha1 struct {
- user, home string
-}
-
-func (a authCookieSha1) FirstData() ([]byte, []byte, AuthStatus) {
- b := make([]byte, 2*len(a.user))
- hex.Encode(b, []byte(a.user))
- return []byte("DBUS_COOKIE_SHA1"), b, AuthContinue
-}
-
-func (a authCookieSha1) HandleData(data []byte) ([]byte, AuthStatus) {
- challenge := make([]byte, len(data)/2)
- _, err := hex.Decode(challenge, data)
- if err != nil {
- return nil, AuthError
- }
- b := bytes.Split(challenge, []byte{' '})
- if len(b) != 3 {
- return nil, AuthError
- }
- context := b[0]
- id := b[1]
- svchallenge := b[2]
- cookie := a.getCookie(context, id)
- if cookie == nil {
- return nil, AuthError
- }
- clchallenge := a.generateChallenge()
- if clchallenge == nil {
- return nil, AuthError
- }
- hash := sha1.New()
- hash.Write(bytes.Join([][]byte{svchallenge, clchallenge, cookie}, []byte{':'}))
- hexhash := make([]byte, 2*hash.Size())
- hex.Encode(hexhash, hash.Sum(nil))
- data = append(clchallenge, ' ')
- data = append(data, hexhash...)
- resp := make([]byte, 2*len(data))
- hex.Encode(resp, data)
- return resp, AuthOk
-}
-
-// getCookie searches for the cookie identified by id in context and returns
-// the cookie content or nil. (Since HandleData can't return a specific error,
-// but only whether an error occured, this function also doesn't bother to
-// return an error.)
-func (a authCookieSha1) getCookie(context, id []byte) []byte {
- file, err := os.Open(a.home + "/.dbus-keyrings/" + string(context))
- if err != nil {
- return nil
- }
- defer file.Close()
- rd := bufio.NewReader(file)
- for {
- line, err := rd.ReadBytes('\n')
- if err != nil {
- return nil
- }
- line = line[:len(line)-1]
- b := bytes.Split(line, []byte{' '})
- if len(b) != 3 {
- return nil
- }
- if bytes.Equal(b[0], id) {
- return b[2]
- }
- }
-}
-
-// generateChallenge returns a random, hex-encoded challenge, or nil on error
-// (see above).
-func (a authCookieSha1) generateChallenge() []byte {
- b := make([]byte, 16)
- n, err := rand.Read(b)
- if err != nil {
- return nil
- }
- if n != 16 {
- return nil
- }
- enc := make([]byte, 32)
- hex.Encode(enc, b)
- return enc
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/call.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/call.go
deleted file mode 100644
index ba6e73f6..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/call.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package dbus
-
-import (
- "errors"
-)
-
-// Call represents a pending or completed method call.
-type Call struct {
- Destination string
- Path ObjectPath
- Method string
- Args []interface{}
-
- // Strobes when the call is complete.
- Done chan *Call
-
- // After completion, the error status. If this is non-nil, it may be an
- // error message from the peer (with Error as its type) or some other error.
- Err error
-
- // Holds the response once the call is done.
- Body []interface{}
-}
-
-var errSignature = errors.New("dbus: mismatched signature")
-
-// Store stores the body of the reply into the provided pointers. It returns
-// an error if the signatures of the body and retvalues don't match, or if
-// the error status is not nil.
-func (c *Call) Store(retvalues ...interface{}) error {
- if c.Err != nil {
- return c.Err
- }
-
- return Store(c.Body, retvalues...)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/conn.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/conn.go
deleted file mode 100644
index a4f53940..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/conn.go
+++ /dev/null
@@ -1,625 +0,0 @@
-package dbus
-
-import (
- "errors"
- "io"
- "os"
- "reflect"
- "strings"
- "sync"
-)
-
-const defaultSystemBusAddress = "unix:path=/var/run/dbus/system_bus_socket"
-
-var (
- systemBus *Conn
- systemBusLck sync.Mutex
- sessionBus *Conn
- sessionBusLck sync.Mutex
-)
-
-// ErrClosed is the error returned by calls on a closed connection.
-var ErrClosed = errors.New("dbus: connection closed by user")
-
-// Conn represents a connection to a message bus (usually, the system or
-// session bus).
-//
-// Connections are either shared or private. Shared connections
-// are shared between calls to the functions that return them. As a result,
-// the methods Close, Auth and Hello must not be called on them.
-//
-// Multiple goroutines may invoke methods on a connection simultaneously.
-type Conn struct {
- transport
-
- busObj BusObject
- unixFD bool
- uuid string
-
- names []string
- namesLck sync.RWMutex
-
- serialLck sync.Mutex
- nextSerial uint32
- serialUsed map[uint32]bool
-
- calls map[uint32]*Call
- callsLck sync.RWMutex
-
- handlers map[ObjectPath]map[string]exportWithMapping
- handlersLck sync.RWMutex
-
- out chan *Message
- closed bool
- outLck sync.RWMutex
-
- signals []chan<- *Signal
- signalsLck sync.Mutex
-
- eavesdropped chan<- *Message
- eavesdroppedLck sync.Mutex
-}
-
-// SessionBus returns a shared connection to the session bus, connecting to it
-// if not already done.
-func SessionBus() (conn *Conn, err error) {
- sessionBusLck.Lock()
- defer sessionBusLck.Unlock()
- if sessionBus != nil {
- return sessionBus, nil
- }
- defer func() {
- if conn != nil {
- sessionBus = conn
- }
- }()
- conn, err = SessionBusPrivate()
- if err != nil {
- return
- }
- if err = conn.Auth(nil); err != nil {
- conn.Close()
- conn = nil
- return
- }
- if err = conn.Hello(); err != nil {
- conn.Close()
- conn = nil
- }
- return
-}
-
-// SessionBusPrivate returns a new private connection to the session bus.
-func SessionBusPrivate() (*Conn, error) {
- address := os.Getenv("DBUS_SESSION_BUS_ADDRESS")
- if address != "" && address != "autolaunch:" {
- return Dial(address)
- }
-
- return sessionBusPlatform()
-}
-
-// SystemBus returns a shared connection to the system bus, connecting to it if
-// not already done.
-func SystemBus() (conn *Conn, err error) {
- systemBusLck.Lock()
- defer systemBusLck.Unlock()
- if systemBus != nil {
- return systemBus, nil
- }
- defer func() {
- if conn != nil {
- systemBus = conn
- }
- }()
- conn, err = SystemBusPrivate()
- if err != nil {
- return
- }
- if err = conn.Auth(nil); err != nil {
- conn.Close()
- conn = nil
- return
- }
- if err = conn.Hello(); err != nil {
- conn.Close()
- conn = nil
- }
- return
-}
-
-// SystemBusPrivate returns a new private connection to the system bus.
-func SystemBusPrivate() (*Conn, error) {
- address := os.Getenv("DBUS_SYSTEM_BUS_ADDRESS")
- if address != "" {
- return Dial(address)
- }
- return Dial(defaultSystemBusAddress)
-}
-
-// Dial establishes a new private connection to the message bus specified by address.
-func Dial(address string) (*Conn, error) {
- tr, err := getTransport(address)
- if err != nil {
- return nil, err
- }
- return newConn(tr)
-}
-
-// NewConn creates a new private *Conn from an already established connection.
-func NewConn(conn io.ReadWriteCloser) (*Conn, error) {
- return newConn(genericTransport{conn})
-}
-
-// newConn creates a new *Conn from a transport.
-func newConn(tr transport) (*Conn, error) {
- conn := new(Conn)
- conn.transport = tr
- conn.calls = make(map[uint32]*Call)
- conn.out = make(chan *Message, 10)
- conn.handlers = make(map[ObjectPath]map[string]exportWithMapping)
- conn.nextSerial = 1
- conn.serialUsed = map[uint32]bool{0: true}
- conn.busObj = conn.Object("org.freedesktop.DBus", "/org/freedesktop/DBus")
- return conn, nil
-}
-
-// BusObject returns the object owned by the bus daemon which handles
-// administrative requests.
-func (conn *Conn) BusObject() BusObject {
- return conn.busObj
-}
-
-// Close closes the connection. Any blocked operations will return with errors
-// and the channels passed to Eavesdrop and Signal are closed. This method must
-// not be called on shared connections.
-func (conn *Conn) Close() error {
- conn.outLck.Lock()
- if conn.closed {
- // inWorker calls Close on read error, the read error may
- // be caused by another caller calling Close to shutdown the
- // dbus connection, a double-close scenario we prevent here.
- conn.outLck.Unlock()
- return nil
- }
- close(conn.out)
- conn.closed = true
- conn.outLck.Unlock()
- conn.signalsLck.Lock()
- for _, ch := range conn.signals {
- close(ch)
- }
- conn.signalsLck.Unlock()
- conn.eavesdroppedLck.Lock()
- if conn.eavesdropped != nil {
- close(conn.eavesdropped)
- }
- conn.eavesdroppedLck.Unlock()
- return conn.transport.Close()
-}
-
-// Eavesdrop causes conn to send all incoming messages to the given channel
-// without further processing. Method replies, errors and signals will not be
-// sent to the appropiate channels and method calls will not be handled. If nil
-// is passed, the normal behaviour is restored.
-//
-// The caller has to make sure that ch is sufficiently buffered;
-// if a message arrives when a write to ch is not possible, the message is
-// discarded.
-func (conn *Conn) Eavesdrop(ch chan<- *Message) {
- conn.eavesdroppedLck.Lock()
- conn.eavesdropped = ch
- conn.eavesdroppedLck.Unlock()
-}
-
-// getSerial returns an unused serial.
-func (conn *Conn) getSerial() uint32 {
- conn.serialLck.Lock()
- defer conn.serialLck.Unlock()
- n := conn.nextSerial
- for conn.serialUsed[n] {
- n++
- }
- conn.serialUsed[n] = true
- conn.nextSerial = n + 1
- return n
-}
-
-// Hello sends the initial org.freedesktop.DBus.Hello call. This method must be
-// called after authentication, but before sending any other messages to the
-// bus. Hello must not be called for shared connections.
-func (conn *Conn) Hello() error {
- var s string
- err := conn.busObj.Call("org.freedesktop.DBus.Hello", 0).Store(&s)
- if err != nil {
- return err
- }
- conn.namesLck.Lock()
- conn.names = make([]string, 1)
- conn.names[0] = s
- conn.namesLck.Unlock()
- return nil
-}
-
-// inWorker runs in an own goroutine, reading incoming messages from the
-// transport and dispatching them appropiately.
-func (conn *Conn) inWorker() {
- for {
- msg, err := conn.ReadMessage()
- if err == nil {
- conn.eavesdroppedLck.Lock()
- if conn.eavesdropped != nil {
- select {
- case conn.eavesdropped <- msg:
- default:
- }
- conn.eavesdroppedLck.Unlock()
- continue
- }
- conn.eavesdroppedLck.Unlock()
- dest, _ := msg.Headers[FieldDestination].value.(string)
- found := false
- if dest == "" {
- found = true
- } else {
- conn.namesLck.RLock()
- if len(conn.names) == 0 {
- found = true
- }
- for _, v := range conn.names {
- if dest == v {
- found = true
- break
- }
- }
- conn.namesLck.RUnlock()
- }
- if !found {
- // Eavesdropped a message, but no channel for it is registered.
- // Ignore it.
- continue
- }
- switch msg.Type {
- case TypeMethodReply, TypeError:
- serial := msg.Headers[FieldReplySerial].value.(uint32)
- conn.callsLck.Lock()
- if c, ok := conn.calls[serial]; ok {
- if msg.Type == TypeError {
- name, _ := msg.Headers[FieldErrorName].value.(string)
- c.Err = Error{name, msg.Body}
- } else {
- c.Body = msg.Body
- }
- c.Done <- c
- conn.serialLck.Lock()
- delete(conn.serialUsed, serial)
- conn.serialLck.Unlock()
- delete(conn.calls, serial)
- }
- conn.callsLck.Unlock()
- case TypeSignal:
- iface := msg.Headers[FieldInterface].value.(string)
- member := msg.Headers[FieldMember].value.(string)
- // as per http://dbus.freedesktop.org/doc/dbus-specification.html ,
- // sender is optional for signals.
- sender, _ := msg.Headers[FieldSender].value.(string)
- if iface == "org.freedesktop.DBus" && sender == "org.freedesktop.DBus" {
- if member == "NameLost" {
- // If we lost the name on the bus, remove it from our
- // tracking list.
- name, ok := msg.Body[0].(string)
- if !ok {
- panic("Unable to read the lost name")
- }
- conn.namesLck.Lock()
- for i, v := range conn.names {
- if v == name {
- conn.names = append(conn.names[:i],
- conn.names[i+1:]...)
- }
- }
- conn.namesLck.Unlock()
- } else if member == "NameAcquired" {
- // If we acquired the name on the bus, add it to our
- // tracking list.
- name, ok := msg.Body[0].(string)
- if !ok {
- panic("Unable to read the acquired name")
- }
- conn.namesLck.Lock()
- conn.names = append(conn.names, name)
- conn.namesLck.Unlock()
- }
- }
- signal := &Signal{
- Sender: sender,
- Path: msg.Headers[FieldPath].value.(ObjectPath),
- Name: iface + "." + member,
- Body: msg.Body,
- }
- conn.signalsLck.Lock()
- for _, ch := range conn.signals {
- ch <- signal
- }
- conn.signalsLck.Unlock()
- case TypeMethodCall:
- go conn.handleCall(msg)
- }
- } else if _, ok := err.(InvalidMessageError); !ok {
- // Some read error occured (usually EOF); we can't really do
- // anything but to shut down all stuff and returns errors to all
- // pending replies.
- conn.Close()
- conn.callsLck.RLock()
- for _, v := range conn.calls {
- v.Err = err
- v.Done <- v
- }
- conn.callsLck.RUnlock()
- return
- }
- // invalid messages are ignored
- }
-}
-
-// Names returns the list of all names that are currently owned by this
-// connection. The slice is always at least one element long, the first element
-// being the unique name of the connection.
-func (conn *Conn) Names() []string {
- conn.namesLck.RLock()
- // copy the slice so it can't be modified
- s := make([]string, len(conn.names))
- copy(s, conn.names)
- conn.namesLck.RUnlock()
- return s
-}
-
-// Object returns the object identified by the given destination name and path.
-func (conn *Conn) Object(dest string, path ObjectPath) BusObject {
- return &Object{conn, dest, path}
-}
-
-// outWorker runs in an own goroutine, encoding and sending messages that are
-// sent to conn.out.
-func (conn *Conn) outWorker() {
- for msg := range conn.out {
- err := conn.SendMessage(msg)
- conn.callsLck.RLock()
- if err != nil {
- if c := conn.calls[msg.serial]; c != nil {
- c.Err = err
- c.Done <- c
- }
- conn.serialLck.Lock()
- delete(conn.serialUsed, msg.serial)
- conn.serialLck.Unlock()
- } else if msg.Type != TypeMethodCall {
- conn.serialLck.Lock()
- delete(conn.serialUsed, msg.serial)
- conn.serialLck.Unlock()
- }
- conn.callsLck.RUnlock()
- }
-}
-
-// Send sends the given message to the message bus. You usually don't need to
-// use this; use the higher-level equivalents (Call / Go, Emit and Export)
-// instead. If msg is a method call and NoReplyExpected is not set, a non-nil
-// call is returned and the same value is sent to ch (which must be buffered)
-// once the call is complete. Otherwise, ch is ignored and a Call structure is
-// returned of which only the Err member is valid.
-func (conn *Conn) Send(msg *Message, ch chan *Call) *Call {
- var call *Call
-
- msg.serial = conn.getSerial()
- if msg.Type == TypeMethodCall && msg.Flags&FlagNoReplyExpected == 0 {
- if ch == nil {
- ch = make(chan *Call, 5)
- } else if cap(ch) == 0 {
- panic("dbus: unbuffered channel passed to (*Conn).Send")
- }
- call = new(Call)
- call.Destination, _ = msg.Headers[FieldDestination].value.(string)
- call.Path, _ = msg.Headers[FieldPath].value.(ObjectPath)
- iface, _ := msg.Headers[FieldInterface].value.(string)
- member, _ := msg.Headers[FieldMember].value.(string)
- call.Method = iface + "." + member
- call.Args = msg.Body
- call.Done = ch
- conn.callsLck.Lock()
- conn.calls[msg.serial] = call
- conn.callsLck.Unlock()
- conn.outLck.RLock()
- if conn.closed {
- call.Err = ErrClosed
- call.Done <- call
- } else {
- conn.out <- msg
- }
- conn.outLck.RUnlock()
- } else {
- conn.outLck.RLock()
- if conn.closed {
- call = &Call{Err: ErrClosed}
- } else {
- conn.out <- msg
- call = &Call{Err: nil}
- }
- conn.outLck.RUnlock()
- }
- return call
-}
-
-// sendError creates an error message corresponding to the parameters and sends
-// it to conn.out.
-func (conn *Conn) sendError(e Error, dest string, serial uint32) {
- msg := new(Message)
- msg.Type = TypeError
- msg.serial = conn.getSerial()
- msg.Headers = make(map[HeaderField]Variant)
- if dest != "" {
- msg.Headers[FieldDestination] = MakeVariant(dest)
- }
- msg.Headers[FieldErrorName] = MakeVariant(e.Name)
- msg.Headers[FieldReplySerial] = MakeVariant(serial)
- msg.Body = e.Body
- if len(e.Body) > 0 {
- msg.Headers[FieldSignature] = MakeVariant(SignatureOf(e.Body...))
- }
- conn.outLck.RLock()
- if !conn.closed {
- conn.out <- msg
- }
- conn.outLck.RUnlock()
-}
-
-// sendReply creates a method reply message corresponding to the parameters and
-// sends it to conn.out.
-func (conn *Conn) sendReply(dest string, serial uint32, values ...interface{}) {
- msg := new(Message)
- msg.Type = TypeMethodReply
- msg.serial = conn.getSerial()
- msg.Headers = make(map[HeaderField]Variant)
- if dest != "" {
- msg.Headers[FieldDestination] = MakeVariant(dest)
- }
- msg.Headers[FieldReplySerial] = MakeVariant(serial)
- msg.Body = values
- if len(values) > 0 {
- msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...))
- }
- conn.outLck.RLock()
- if !conn.closed {
- conn.out <- msg
- }
- conn.outLck.RUnlock()
-}
-
-// Signal registers the given channel to be passed all received signal messages.
-// The caller has to make sure that ch is sufficiently buffered; if a message
-// arrives when a write to c is not possible, it is discarded.
-//
-// Multiple of these channels can be registered at the same time. Passing a
-// channel that already is registered will remove it from the list of the
-// registered channels.
-//
-// These channels are "overwritten" by Eavesdrop; i.e., if there currently is a
-// channel for eavesdropped messages, this channel receives all signals, and
-// none of the channels passed to Signal will receive any signals.
-func (conn *Conn) Signal(ch chan<- *Signal) {
- conn.signalsLck.Lock()
- conn.signals = append(conn.signals, ch)
- conn.signalsLck.Unlock()
-}
-
-// SupportsUnixFDs returns whether the underlying transport supports passing of
-// unix file descriptors. If this is false, method calls containing unix file
-// descriptors will return an error and emitted signals containing them will
-// not be sent.
-func (conn *Conn) SupportsUnixFDs() bool {
- return conn.unixFD
-}
-
-// Error represents a D-Bus message of type Error.
-type Error struct {
- Name string
- Body []interface{}
-}
-
-func NewError(name string, body []interface{}) *Error {
- return &Error{name, body}
-}
-
-func (e Error) Error() string {
- if len(e.Body) >= 1 {
- s, ok := e.Body[0].(string)
- if ok {
- return s
- }
- }
- return e.Name
-}
-
-// Signal represents a D-Bus message of type Signal. The name member is given in
-// "interface.member" notation, e.g. org.freedesktop.D-Bus.NameLost.
-type Signal struct {
- Sender string
- Path ObjectPath
- Name string
- Body []interface{}
-}
-
-// transport is a D-Bus transport.
-type transport interface {
- // Read and Write raw data (for example, for the authentication protocol).
- io.ReadWriteCloser
-
- // Send the initial null byte used for the EXTERNAL mechanism.
- SendNullByte() error
-
- // Returns whether this transport supports passing Unix FDs.
- SupportsUnixFDs() bool
-
- // Signal the transport that Unix FD passing is enabled for this connection.
- EnableUnixFDs()
-
- // Read / send a message, handling things like Unix FDs.
- ReadMessage() (*Message, error)
- SendMessage(*Message) error
-}
-
-var (
- transports = make(map[string]func(string) (transport, error))
-)
-
-func getTransport(address string) (transport, error) {
- var err error
- var t transport
-
- addresses := strings.Split(address, ";")
- for _, v := range addresses {
- i := strings.IndexRune(v, ':')
- if i == -1 {
- err = errors.New("dbus: invalid bus address (no transport)")
- continue
- }
- f := transports[v[:i]]
- if f == nil {
- err = errors.New("dbus: invalid bus address (invalid or unsupported transport)")
- continue
- }
- t, err = f(v[i+1:])
- if err == nil {
- return t, nil
- }
- }
- return nil, err
-}
-
-// dereferenceAll returns a slice that, assuming that vs is a slice of pointers
-// of arbitrary types, containes the values that are obtained from dereferencing
-// all elements in vs.
-func dereferenceAll(vs []interface{}) []interface{} {
- for i := range vs {
- v := reflect.ValueOf(vs[i])
- v = v.Elem()
- vs[i] = v.Interface()
- }
- return vs
-}
-
-// getKey gets a key from a the list of keys. Returns "" on error / not found...
-func getKey(s, key string) string {
- i := strings.Index(s, key)
- if i == -1 {
- return ""
- }
- if i+len(key)+1 >= len(s) || s[i+len(key)] != '=' {
- return ""
- }
- j := strings.Index(s, ",")
- if j == -1 {
- j = len(s)
- }
- return s[i+len(key)+1 : j]
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/conn_darwin.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/conn_darwin.go
deleted file mode 100644
index b67bb1b8..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/conn_darwin.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package dbus
-
-import (
- "errors"
- "os/exec"
-)
-
-func sessionBusPlatform() (*Conn, error) {
- cmd := exec.Command("launchctl", "getenv", "DBUS_LAUNCHD_SESSION_BUS_SOCKET")
- b, err := cmd.CombinedOutput()
-
- if err != nil {
- return nil, err
- }
-
- if len(b) == 0 {
- return nil, errors.New("dbus: couldn't determine address of session bus")
- }
-
- return Dial("unix:path=" + string(b[:len(b)-1]))
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/conn_other.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/conn_other.go
deleted file mode 100644
index f74b8758..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/conn_other.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// +build !darwin
-
-package dbus
-
-import (
- "bytes"
- "errors"
- "os/exec"
-)
-
-func sessionBusPlatform() (*Conn, error) {
- cmd := exec.Command("dbus-launch")
- b, err := cmd.CombinedOutput()
-
- if err != nil {
- return nil, err
- }
-
- i := bytes.IndexByte(b, '=')
- j := bytes.IndexByte(b, '\n')
-
- if i == -1 || j == -1 {
- return nil, errors.New("dbus: couldn't determine address of session bus")
- }
-
- return Dial(string(b[i+1 : j]))
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/dbus.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/dbus.go
deleted file mode 100644
index 2ce68735..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/dbus.go
+++ /dev/null
@@ -1,258 +0,0 @@
-package dbus
-
-import (
- "errors"
- "reflect"
- "strings"
-)
-
-var (
- byteType = reflect.TypeOf(byte(0))
- boolType = reflect.TypeOf(false)
- uint8Type = reflect.TypeOf(uint8(0))
- int16Type = reflect.TypeOf(int16(0))
- uint16Type = reflect.TypeOf(uint16(0))
- int32Type = reflect.TypeOf(int32(0))
- uint32Type = reflect.TypeOf(uint32(0))
- int64Type = reflect.TypeOf(int64(0))
- uint64Type = reflect.TypeOf(uint64(0))
- float64Type = reflect.TypeOf(float64(0))
- stringType = reflect.TypeOf("")
- signatureType = reflect.TypeOf(Signature{""})
- objectPathType = reflect.TypeOf(ObjectPath(""))
- variantType = reflect.TypeOf(Variant{Signature{""}, nil})
- interfacesType = reflect.TypeOf([]interface{}{})
- unixFDType = reflect.TypeOf(UnixFD(0))
- unixFDIndexType = reflect.TypeOf(UnixFDIndex(0))
-)
-
-// An InvalidTypeError signals that a value which cannot be represented in the
-// D-Bus wire format was passed to a function.
-type InvalidTypeError struct {
- Type reflect.Type
-}
-
-func (e InvalidTypeError) Error() string {
- return "dbus: invalid type " + e.Type.String()
-}
-
-// Store copies the values contained in src to dest, which must be a slice of
-// pointers. It converts slices of interfaces from src to corresponding structs
-// in dest. An error is returned if the lengths of src and dest or the types of
-// their elements don't match.
-func Store(src []interface{}, dest ...interface{}) error {
- if len(src) != len(dest) {
- return errors.New("dbus.Store: length mismatch")
- }
-
- for i := range src {
- if err := store(src[i], dest[i]); err != nil {
- return err
- }
- }
- return nil
-}
-
-func store(src, dest interface{}) error {
- if reflect.TypeOf(dest).Elem() == reflect.TypeOf(src) {
- reflect.ValueOf(dest).Elem().Set(reflect.ValueOf(src))
- return nil
- } else if hasStruct(dest) {
- rv := reflect.ValueOf(dest).Elem()
- switch rv.Kind() {
- case reflect.Struct:
- vs, ok := src.([]interface{})
- if !ok {
- return errors.New("dbus.Store: type mismatch")
- }
- t := rv.Type()
- ndest := make([]interface{}, 0, rv.NumField())
- for i := 0; i < rv.NumField(); i++ {
- field := t.Field(i)
- if field.PkgPath == "" && field.Tag.Get("dbus") != "-" {
- ndest = append(ndest, rv.Field(i).Addr().Interface())
- }
- }
- if len(vs) != len(ndest) {
- return errors.New("dbus.Store: type mismatch")
- }
- err := Store(vs, ndest...)
- if err != nil {
- return errors.New("dbus.Store: type mismatch")
- }
- case reflect.Slice:
- sv := reflect.ValueOf(src)
- if sv.Kind() != reflect.Slice {
- return errors.New("dbus.Store: type mismatch")
- }
- rv.Set(reflect.MakeSlice(rv.Type(), sv.Len(), sv.Len()))
- for i := 0; i < sv.Len(); i++ {
- if err := store(sv.Index(i).Interface(), rv.Index(i).Addr().Interface()); err != nil {
- return err
- }
- }
- case reflect.Map:
- sv := reflect.ValueOf(src)
- if sv.Kind() != reflect.Map {
- return errors.New("dbus.Store: type mismatch")
- }
- keys := sv.MapKeys()
- rv.Set(reflect.MakeMap(sv.Type()))
- for _, key := range keys {
- v := reflect.New(sv.Type().Elem())
- if err := store(v, sv.MapIndex(key).Interface()); err != nil {
- return err
- }
- rv.SetMapIndex(key, v.Elem())
- }
- default:
- return errors.New("dbus.Store: type mismatch")
- }
- return nil
- } else {
- return errors.New("dbus.Store: type mismatch")
- }
-}
-
-func hasStruct(v interface{}) bool {
- t := reflect.TypeOf(v)
- for {
- switch t.Kind() {
- case reflect.Struct:
- return true
- case reflect.Slice, reflect.Ptr, reflect.Map:
- t = t.Elem()
- default:
- return false
- }
- }
-}
-
-// An ObjectPath is an object path as defined by the D-Bus spec.
-type ObjectPath string
-
-// IsValid returns whether the object path is valid.
-func (o ObjectPath) IsValid() bool {
- s := string(o)
- if len(s) == 0 {
- return false
- }
- if s[0] != '/' {
- return false
- }
- if s[len(s)-1] == '/' && len(s) != 1 {
- return false
- }
- // probably not used, but technically possible
- if s == "/" {
- return true
- }
- split := strings.Split(s[1:], "/")
- for _, v := range split {
- if len(v) == 0 {
- return false
- }
- for _, c := range v {
- if !isMemberChar(c) {
- return false
- }
- }
- }
- return true
-}
-
-// A UnixFD is a Unix file descriptor sent over the wire. See the package-level
-// documentation for more information about Unix file descriptor passsing.
-type UnixFD int32
-
-// A UnixFDIndex is the representation of a Unix file descriptor in a message.
-type UnixFDIndex uint32
-
-// alignment returns the alignment of values of type t.
-func alignment(t reflect.Type) int {
- switch t {
- case variantType:
- return 1
- case objectPathType:
- return 4
- case signatureType:
- return 1
- case interfacesType: // sometimes used for structs
- return 8
- }
- switch t.Kind() {
- case reflect.Uint8:
- return 1
- case reflect.Uint16, reflect.Int16:
- return 2
- case reflect.Uint32, reflect.Int32, reflect.String, reflect.Array, reflect.Slice, reflect.Map:
- return 4
- case reflect.Uint64, reflect.Int64, reflect.Float64, reflect.Struct:
- return 8
- case reflect.Ptr:
- return alignment(t.Elem())
- }
- return 1
-}
-
-// isKeyType returns whether t is a valid type for a D-Bus dict.
-func isKeyType(t reflect.Type) bool {
- switch t.Kind() {
- case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
- reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float64,
- reflect.String:
-
- return true
- }
- return false
-}
-
-// isValidInterface returns whether s is a valid name for an interface.
-func isValidInterface(s string) bool {
- if len(s) == 0 || len(s) > 255 || s[0] == '.' {
- return false
- }
- elem := strings.Split(s, ".")
- if len(elem) < 2 {
- return false
- }
- for _, v := range elem {
- if len(v) == 0 {
- return false
- }
- if v[0] >= '0' && v[0] <= '9' {
- return false
- }
- for _, c := range v {
- if !isMemberChar(c) {
- return false
- }
- }
- }
- return true
-}
-
-// isValidMember returns whether s is a valid name for a member.
-func isValidMember(s string) bool {
- if len(s) == 0 || len(s) > 255 {
- return false
- }
- i := strings.Index(s, ".")
- if i != -1 {
- return false
- }
- if s[0] >= '0' && s[0] <= '9' {
- return false
- }
- for _, c := range s {
- if !isMemberChar(c) {
- return false
- }
- }
- return true
-}
-
-func isMemberChar(c rune) bool {
- return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') ||
- (c >= 'a' && c <= 'z') || c == '_'
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/decoder.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/decoder.go
deleted file mode 100644
index ef50dcab..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/decoder.go
+++ /dev/null
@@ -1,228 +0,0 @@
-package dbus
-
-import (
- "encoding/binary"
- "io"
- "reflect"
-)
-
-type decoder struct {
- in io.Reader
- order binary.ByteOrder
- pos int
-}
-
-// newDecoder returns a new decoder that reads values from in. The input is
-// expected to be in the given byte order.
-func newDecoder(in io.Reader, order binary.ByteOrder) *decoder {
- dec := new(decoder)
- dec.in = in
- dec.order = order
- return dec
-}
-
-// align aligns the input to the given boundary and panics on error.
-func (dec *decoder) align(n int) {
- if dec.pos%n != 0 {
- newpos := (dec.pos + n - 1) & ^(n - 1)
- empty := make([]byte, newpos-dec.pos)
- if _, err := io.ReadFull(dec.in, empty); err != nil {
- panic(err)
- }
- dec.pos = newpos
- }
-}
-
-// Calls binary.Read(dec.in, dec.order, v) and panics on read errors.
-func (dec *decoder) binread(v interface{}) {
- if err := binary.Read(dec.in, dec.order, v); err != nil {
- panic(err)
- }
-}
-
-func (dec *decoder) Decode(sig Signature) (vs []interface{}, err error) {
- defer func() {
- var ok bool
- v := recover()
- if err, ok = v.(error); ok {
- if err == io.EOF || err == io.ErrUnexpectedEOF {
- err = FormatError("unexpected EOF")
- }
- }
- }()
- vs = make([]interface{}, 0)
- s := sig.str
- for s != "" {
- err, rem := validSingle(s, 0)
- if err != nil {
- return nil, err
- }
- v := dec.decode(s[:len(s)-len(rem)], 0)
- vs = append(vs, v)
- s = rem
- }
- return vs, nil
-}
-
-func (dec *decoder) decode(s string, depth int) interface{} {
- dec.align(alignment(typeFor(s)))
- switch s[0] {
- case 'y':
- var b [1]byte
- if _, err := dec.in.Read(b[:]); err != nil {
- panic(err)
- }
- dec.pos++
- return b[0]
- case 'b':
- i := dec.decode("u", depth).(uint32)
- switch {
- case i == 0:
- return false
- case i == 1:
- return true
- default:
- panic(FormatError("invalid value for boolean"))
- }
- case 'n':
- var i int16
- dec.binread(&i)
- dec.pos += 2
- return i
- case 'i':
- var i int32
- dec.binread(&i)
- dec.pos += 4
- return i
- case 'x':
- var i int64
- dec.binread(&i)
- dec.pos += 8
- return i
- case 'q':
- var i uint16
- dec.binread(&i)
- dec.pos += 2
- return i
- case 'u':
- var i uint32
- dec.binread(&i)
- dec.pos += 4
- return i
- case 't':
- var i uint64
- dec.binread(&i)
- dec.pos += 8
- return i
- case 'd':
- var f float64
- dec.binread(&f)
- dec.pos += 8
- return f
- case 's':
- length := dec.decode("u", depth).(uint32)
- b := make([]byte, int(length)+1)
- if _, err := io.ReadFull(dec.in, b); err != nil {
- panic(err)
- }
- dec.pos += int(length) + 1
- return string(b[:len(b)-1])
- case 'o':
- return ObjectPath(dec.decode("s", depth).(string))
- case 'g':
- length := dec.decode("y", depth).(byte)
- b := make([]byte, int(length)+1)
- if _, err := io.ReadFull(dec.in, b); err != nil {
- panic(err)
- }
- dec.pos += int(length) + 1
- sig, err := ParseSignature(string(b[:len(b)-1]))
- if err != nil {
- panic(err)
- }
- return sig
- case 'v':
- if depth >= 64 {
- panic(FormatError("input exceeds container depth limit"))
- }
- var variant Variant
- sig := dec.decode("g", depth).(Signature)
- if len(sig.str) == 0 {
- panic(FormatError("variant signature is empty"))
- }
- err, rem := validSingle(sig.str, 0)
- if err != nil {
- panic(err)
- }
- if rem != "" {
- panic(FormatError("variant signature has multiple types"))
- }
- variant.sig = sig
- variant.value = dec.decode(sig.str, depth+1)
- return variant
- case 'h':
- return UnixFDIndex(dec.decode("u", depth).(uint32))
- case 'a':
- if len(s) > 1 && s[1] == '{' {
- ksig := s[2:3]
- vsig := s[3 : len(s)-1]
- v := reflect.MakeMap(reflect.MapOf(typeFor(ksig), typeFor(vsig)))
- if depth >= 63 {
- panic(FormatError("input exceeds container depth limit"))
- }
- length := dec.decode("u", depth).(uint32)
- // Even for empty maps, the correct padding must be included
- dec.align(8)
- spos := dec.pos
- for dec.pos < spos+int(length) {
- dec.align(8)
- if !isKeyType(v.Type().Key()) {
- panic(InvalidTypeError{v.Type()})
- }
- kv := dec.decode(ksig, depth+2)
- vv := dec.decode(vsig, depth+2)
- v.SetMapIndex(reflect.ValueOf(kv), reflect.ValueOf(vv))
- }
- return v.Interface()
- }
- if depth >= 64 {
- panic(FormatError("input exceeds container depth limit"))
- }
- length := dec.decode("u", depth).(uint32)
- v := reflect.MakeSlice(reflect.SliceOf(typeFor(s[1:])), 0, int(length))
- // Even for empty arrays, the correct padding must be included
- dec.align(alignment(typeFor(s[1:])))
- spos := dec.pos
- for dec.pos < spos+int(length) {
- ev := dec.decode(s[1:], depth+1)
- v = reflect.Append(v, reflect.ValueOf(ev))
- }
- return v.Interface()
- case '(':
- if depth >= 64 {
- panic(FormatError("input exceeds container depth limit"))
- }
- dec.align(8)
- v := make([]interface{}, 0)
- s = s[1 : len(s)-1]
- for s != "" {
- err, rem := validSingle(s, 0)
- if err != nil {
- panic(err)
- }
- ev := dec.decode(s[:len(s)-len(rem)], depth+1)
- v = append(v, ev)
- s = rem
- }
- return v
- default:
- panic(SignatureError{Sig: s})
- }
-}
-
-// A FormatError is an error in the wire format.
-type FormatError string
-
-func (e FormatError) Error() string {
- return "dbus: wire format error: " + string(e)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/doc.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/doc.go
deleted file mode 100644
index deff554a..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/doc.go
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
-Package dbus implements bindings to the D-Bus message bus system.
-
-To use the message bus API, you first need to connect to a bus (usually the
-session or system bus). The acquired connection then can be used to call methods
-on remote objects and emit or receive signals. Using the Export method, you can
-arrange D-Bus methods calls to be directly translated to method calls on a Go
-value.
-
-Conversion Rules
-
-For outgoing messages, Go types are automatically converted to the
-corresponding D-Bus types. The following types are directly encoded as their
-respective D-Bus equivalents:
-
- Go type | D-Bus type
- ------------+-----------
- byte | BYTE
- bool | BOOLEAN
- int16 | INT16
- uint16 | UINT16
- int32 | INT32
- uint32 | UINT32
- int64 | INT64
- uint64 | UINT64
- float64 | DOUBLE
- string | STRING
- ObjectPath | OBJECT_PATH
- Signature | SIGNATURE
- Variant | VARIANT
- UnixFDIndex | UNIX_FD
-
-Slices and arrays encode as ARRAYs of their element type.
-
-Maps encode as DICTs, provided that their key type can be used as a key for
-a DICT.
-
-Structs other than Variant and Signature encode as a STRUCT containing their
-exported fields. Fields whose tags contain `dbus:"-"` and unexported fields will
-be skipped.
-
-Pointers encode as the value they're pointed to.
-
-Trying to encode any other type or a slice, map or struct containing an
-unsupported type will result in an InvalidTypeError.
-
-For incoming messages, the inverse of these rules are used, with the exception
-of STRUCTs. Incoming STRUCTS are represented as a slice of empty interfaces
-containing the struct fields in the correct order. The Store function can be
-used to convert such values to Go structs.
-
-Unix FD passing
-
-Handling Unix file descriptors deserves special mention. To use them, you should
-first check that they are supported on a connection by calling SupportsUnixFDs.
-If it returns true, all method of Connection will translate messages containing
-UnixFD's to messages that are accompanied by the given file descriptors with the
-UnixFD values being substituted by the correct indices. Similarily, the indices
-of incoming messages are automatically resolved. It shouldn't be necessary to use
-UnixFDIndex.
-
-*/
-package dbus
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/encoder.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/encoder.go
deleted file mode 100644
index 9f0a9e89..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/encoder.go
+++ /dev/null
@@ -1,208 +0,0 @@
-package dbus
-
-import (
- "bytes"
- "encoding/binary"
- "io"
- "reflect"
-)
-
-// An encoder encodes values to the D-Bus wire format.
-type encoder struct {
- out io.Writer
- order binary.ByteOrder
- pos int
-}
-
-// NewEncoder returns a new encoder that writes to out in the given byte order.
-func newEncoder(out io.Writer, order binary.ByteOrder) *encoder {
- return newEncoderAtOffset(out, 0, order)
-}
-
-// newEncoderAtOffset returns a new encoder that writes to out in the given
-// byte order. Specify the offset to initialize pos for proper alignment
-// computation.
-func newEncoderAtOffset(out io.Writer, offset int, order binary.ByteOrder) *encoder {
- enc := new(encoder)
- enc.out = out
- enc.order = order
- enc.pos = offset
- return enc
-}
-
-// Aligns the next output to be on a multiple of n. Panics on write errors.
-func (enc *encoder) align(n int) {
- pad := enc.padding(0, n)
- if pad > 0 {
- empty := make([]byte, pad)
- if _, err := enc.out.Write(empty); err != nil {
- panic(err)
- }
- enc.pos += pad
- }
-}
-
-// pad returns the number of bytes of padding, based on current position and additional offset.
-// and alignment.
-func (enc *encoder) padding(offset, algn int) int {
- abs := enc.pos + offset
- if abs%algn != 0 {
- newabs := (abs + algn - 1) & ^(algn - 1)
- return newabs - abs
- }
- return 0
-}
-
-// Calls binary.Write(enc.out, enc.order, v) and panics on write errors.
-func (enc *encoder) binwrite(v interface{}) {
- if err := binary.Write(enc.out, enc.order, v); err != nil {
- panic(err)
- }
-}
-
-// Encode encodes the given values to the underyling reader. All written values
-// are aligned properly as required by the D-Bus spec.
-func (enc *encoder) Encode(vs ...interface{}) (err error) {
- defer func() {
- err, _ = recover().(error)
- }()
- for _, v := range vs {
- enc.encode(reflect.ValueOf(v), 0)
- }
- return nil
-}
-
-// encode encodes the given value to the writer and panics on error. depth holds
-// the depth of the container nesting.
-func (enc *encoder) encode(v reflect.Value, depth int) {
- enc.align(alignment(v.Type()))
- switch v.Kind() {
- case reflect.Uint8:
- var b [1]byte
- b[0] = byte(v.Uint())
- if _, err := enc.out.Write(b[:]); err != nil {
- panic(err)
- }
- enc.pos++
- case reflect.Bool:
- if v.Bool() {
- enc.encode(reflect.ValueOf(uint32(1)), depth)
- } else {
- enc.encode(reflect.ValueOf(uint32(0)), depth)
- }
- case reflect.Int16:
- enc.binwrite(int16(v.Int()))
- enc.pos += 2
- case reflect.Uint16:
- enc.binwrite(uint16(v.Uint()))
- enc.pos += 2
- case reflect.Int32:
- enc.binwrite(int32(v.Int()))
- enc.pos += 4
- case reflect.Uint32:
- enc.binwrite(uint32(v.Uint()))
- enc.pos += 4
- case reflect.Int64:
- enc.binwrite(v.Int())
- enc.pos += 8
- case reflect.Uint64:
- enc.binwrite(v.Uint())
- enc.pos += 8
- case reflect.Float64:
- enc.binwrite(v.Float())
- enc.pos += 8
- case reflect.String:
- enc.encode(reflect.ValueOf(uint32(len(v.String()))), depth)
- b := make([]byte, v.Len()+1)
- copy(b, v.String())
- b[len(b)-1] = 0
- n, err := enc.out.Write(b)
- if err != nil {
- panic(err)
- }
- enc.pos += n
- case reflect.Ptr:
- enc.encode(v.Elem(), depth)
- case reflect.Slice, reflect.Array:
- if depth >= 64 {
- panic(FormatError("input exceeds container depth limit"))
- }
- // Lookahead offset: 4 bytes for uint32 length (with alignment),
- // plus alignment for elements.
- n := enc.padding(0, 4) + 4
- offset := enc.pos + n + enc.padding(n, alignment(v.Type().Elem()))
-
- var buf bytes.Buffer
- bufenc := newEncoderAtOffset(&buf, offset, enc.order)
-
- for i := 0; i < v.Len(); i++ {
- bufenc.encode(v.Index(i), depth+1)
- }
- enc.encode(reflect.ValueOf(uint32(buf.Len())), depth)
- length := buf.Len()
- enc.align(alignment(v.Type().Elem()))
- if _, err := buf.WriteTo(enc.out); err != nil {
- panic(err)
- }
- enc.pos += length
- case reflect.Struct:
- if depth >= 64 && v.Type() != signatureType {
- panic(FormatError("input exceeds container depth limit"))
- }
- switch t := v.Type(); t {
- case signatureType:
- str := v.Field(0)
- enc.encode(reflect.ValueOf(byte(str.Len())), depth+1)
- b := make([]byte, str.Len()+1)
- copy(b, str.String())
- b[len(b)-1] = 0
- n, err := enc.out.Write(b)
- if err != nil {
- panic(err)
- }
- enc.pos += n
- case variantType:
- variant := v.Interface().(Variant)
- enc.encode(reflect.ValueOf(variant.sig), depth+1)
- enc.encode(reflect.ValueOf(variant.value), depth+1)
- default:
- for i := 0; i < v.Type().NumField(); i++ {
- field := t.Field(i)
- if field.PkgPath == "" && field.Tag.Get("dbus") != "-" {
- enc.encode(v.Field(i), depth+1)
- }
- }
- }
- case reflect.Map:
- // Maps are arrays of structures, so they actually increase the depth by
- // 2.
- if depth >= 63 {
- panic(FormatError("input exceeds container depth limit"))
- }
- if !isKeyType(v.Type().Key()) {
- panic(InvalidTypeError{v.Type()})
- }
- keys := v.MapKeys()
- // Lookahead offset: 4 bytes for uint32 length (with alignment),
- // plus 8-byte alignment
- n := enc.padding(0, 4) + 4
- offset := enc.pos + n + enc.padding(n, 8)
-
- var buf bytes.Buffer
- bufenc := newEncoderAtOffset(&buf, offset, enc.order)
- for _, k := range keys {
- bufenc.align(8)
- bufenc.encode(k, depth+2)
- bufenc.encode(v.MapIndex(k), depth+2)
- }
- enc.encode(reflect.ValueOf(uint32(buf.Len())), depth)
- length := buf.Len()
- enc.align(8)
- if _, err := buf.WriteTo(enc.out); err != nil {
- panic(err)
- }
- enc.pos += length
- default:
- panic(InvalidTypeError{v.Type()})
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/export.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/export.go
deleted file mode 100644
index c6440a74..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/export.go
+++ /dev/null
@@ -1,411 +0,0 @@
-package dbus
-
-import (
- "errors"
- "fmt"
- "reflect"
- "strings"
-)
-
-var (
- errmsgInvalidArg = Error{
- "org.freedesktop.DBus.Error.InvalidArgs",
- []interface{}{"Invalid type / number of args"},
- }
- errmsgNoObject = Error{
- "org.freedesktop.DBus.Error.NoSuchObject",
- []interface{}{"No such object"},
- }
- errmsgUnknownMethod = Error{
- "org.freedesktop.DBus.Error.UnknownMethod",
- []interface{}{"Unknown / invalid method"},
- }
-)
-
-// exportWithMapping represents an exported struct along with a method name
-// mapping to allow for exporting lower-case methods, etc.
-type exportWithMapping struct {
- export interface{}
-
- // Method name mapping; key -> struct method, value -> dbus method.
- mapping map[string]string
-
- // Whether or not this export is for the entire subtree
- includeSubtree bool
-}
-
-// Sender is a type which can be used in exported methods to receive the message
-// sender.
-type Sender string
-
-func exportedMethod(export exportWithMapping, name string) reflect.Value {
- if export.export == nil {
- return reflect.Value{}
- }
-
- // If a mapping was included in the export, check the map to see if we
- // should be looking for a different method in the export.
- if export.mapping != nil {
- for key, value := range export.mapping {
- if value == name {
- name = key
- break
- }
-
- // Catch the case where a method is aliased but the client is calling
- // the original, e.g. the "Foo" method was exported mapped to
- // "foo," and dbus client called the original "Foo."
- if key == name {
- return reflect.Value{}
- }
- }
- }
-
- value := reflect.ValueOf(export.export)
- m := value.MethodByName(name)
-
- // Catch the case of attempting to call an unexported method
- method, ok := value.Type().MethodByName(name)
-
- if !m.IsValid() || !ok || method.PkgPath != "" {
- return reflect.Value{}
- }
- t := m.Type()
- if t.NumOut() == 0 ||
- t.Out(t.NumOut()-1) != reflect.TypeOf(&errmsgInvalidArg) {
-
- return reflect.Value{}
- }
- return m
-}
-
-// searchHandlers will look through all registered handlers looking for one
-// to handle the given path. If a verbatim one isn't found, it will check for
-// a subtree registration for the path as well.
-func (conn *Conn) searchHandlers(path ObjectPath) (map[string]exportWithMapping, bool) {
- conn.handlersLck.RLock()
- defer conn.handlersLck.RUnlock()
-
- handlers, ok := conn.handlers[path]
- if ok {
- return handlers, ok
- }
-
- // If handlers weren't found for this exact path, look for a matching subtree
- // registration
- handlers = make(map[string]exportWithMapping)
- path = path[:strings.LastIndex(string(path), "/")]
- for len(path) > 0 {
- var subtreeHandlers map[string]exportWithMapping
- subtreeHandlers, ok = conn.handlers[path]
- if ok {
- for iface, handler := range subtreeHandlers {
- // Only include this handler if it registered for the subtree
- if handler.includeSubtree {
- handlers[iface] = handler
- }
- }
-
- break
- }
-
- path = path[:strings.LastIndex(string(path), "/")]
- }
-
- return handlers, ok
-}
-
-// handleCall handles the given method call (i.e. looks if it's one of the
-// pre-implemented ones and searches for a corresponding handler if not).
-func (conn *Conn) handleCall(msg *Message) {
- name := msg.Headers[FieldMember].value.(string)
- path := msg.Headers[FieldPath].value.(ObjectPath)
- ifaceName, hasIface := msg.Headers[FieldInterface].value.(string)
- sender, hasSender := msg.Headers[FieldSender].value.(string)
- serial := msg.serial
- if ifaceName == "org.freedesktop.DBus.Peer" {
- switch name {
- case "Ping":
- conn.sendReply(sender, serial)
- case "GetMachineId":
- conn.sendReply(sender, serial, conn.uuid)
- default:
- conn.sendError(errmsgUnknownMethod, sender, serial)
- }
- return
- }
- if len(name) == 0 {
- conn.sendError(errmsgUnknownMethod, sender, serial)
- }
-
- // Find the exported handler (if any) for this path
- handlers, ok := conn.searchHandlers(path)
- if !ok {
- conn.sendError(errmsgNoObject, sender, serial)
- return
- }
-
- var m reflect.Value
- if hasIface {
- iface := handlers[ifaceName]
- m = exportedMethod(iface, name)
- } else {
- for _, v := range handlers {
- m = exportedMethod(v, name)
- if m.IsValid() {
- break
- }
- }
- }
-
- if !m.IsValid() {
- conn.sendError(errmsgUnknownMethod, sender, serial)
- return
- }
-
- t := m.Type()
- vs := msg.Body
- pointers := make([]interface{}, t.NumIn())
- decode := make([]interface{}, 0, len(vs))
- for i := 0; i < t.NumIn(); i++ {
- tp := t.In(i)
- val := reflect.New(tp)
- pointers[i] = val.Interface()
- if tp == reflect.TypeOf((*Sender)(nil)).Elem() {
- val.Elem().SetString(sender)
- } else if tp == reflect.TypeOf((*Message)(nil)).Elem() {
- val.Elem().Set(reflect.ValueOf(*msg))
- } else {
- decode = append(decode, pointers[i])
- }
- }
-
- if len(decode) != len(vs) {
- conn.sendError(errmsgInvalidArg, sender, serial)
- return
- }
-
- if err := Store(vs, decode...); err != nil {
- conn.sendError(errmsgInvalidArg, sender, serial)
- return
- }
-
- // Extract parameters
- params := make([]reflect.Value, len(pointers))
- for i := 0; i < len(pointers); i++ {
- params[i] = reflect.ValueOf(pointers[i]).Elem()
- }
-
- // Call method
- ret := m.Call(params)
- if em := ret[t.NumOut()-1].Interface().(*Error); em != nil {
- conn.sendError(*em, sender, serial)
- return
- }
-
- if msg.Flags&FlagNoReplyExpected == 0 {
- reply := new(Message)
- reply.Type = TypeMethodReply
- reply.serial = conn.getSerial()
- reply.Headers = make(map[HeaderField]Variant)
- if hasSender {
- reply.Headers[FieldDestination] = msg.Headers[FieldSender]
- }
- reply.Headers[FieldReplySerial] = MakeVariant(msg.serial)
- reply.Body = make([]interface{}, len(ret)-1)
- for i := 0; i < len(ret)-1; i++ {
- reply.Body[i] = ret[i].Interface()
- }
- if len(ret) != 1 {
- reply.Headers[FieldSignature] = MakeVariant(SignatureOf(reply.Body...))
- }
- conn.outLck.RLock()
- if !conn.closed {
- conn.out <- reply
- }
- conn.outLck.RUnlock()
- }
-}
-
-// Emit emits the given signal on the message bus. The name parameter must be
-// formatted as "interface.member", e.g., "org.freedesktop.DBus.NameLost".
-func (conn *Conn) Emit(path ObjectPath, name string, values ...interface{}) error {
- if !path.IsValid() {
- return errors.New("dbus: invalid object path")
- }
- i := strings.LastIndex(name, ".")
- if i == -1 {
- return errors.New("dbus: invalid method name")
- }
- iface := name[:i]
- member := name[i+1:]
- if !isValidMember(member) {
- return errors.New("dbus: invalid method name")
- }
- if !isValidInterface(iface) {
- return errors.New("dbus: invalid interface name")
- }
- msg := new(Message)
- msg.Type = TypeSignal
- msg.serial = conn.getSerial()
- msg.Headers = make(map[HeaderField]Variant)
- msg.Headers[FieldInterface] = MakeVariant(iface)
- msg.Headers[FieldMember] = MakeVariant(member)
- msg.Headers[FieldPath] = MakeVariant(path)
- msg.Body = values
- if len(values) > 0 {
- msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...))
- }
- conn.outLck.RLock()
- defer conn.outLck.RUnlock()
- if conn.closed {
- return ErrClosed
- }
- conn.out <- msg
- return nil
-}
-
-// Export registers the given value to be exported as an object on the
-// message bus.
-//
-// If a method call on the given path and interface is received, an exported
-// method with the same name is called with v as the receiver if the
-// parameters match and the last return value is of type *Error. If this
-// *Error is not nil, it is sent back to the caller as an error.
-// Otherwise, a method reply is sent with the other return values as its body.
-//
-// Any parameters with the special type Sender are set to the sender of the
-// dbus message when the method is called. Parameters of this type do not
-// contribute to the dbus signature of the method (i.e. the method is exposed
-// as if the parameters of type Sender were not there).
-//
-// Similarly, any parameters with the type Message are set to the raw message
-// received on the bus. Again, parameters of this type do not contribute to the
-// dbus signature of the method.
-//
-// Every method call is executed in a new goroutine, so the method may be called
-// in multiple goroutines at once.
-//
-// Method calls on the interface org.freedesktop.DBus.Peer will be automatically
-// handled for every object.
-//
-// Passing nil as the first parameter will cause conn to cease handling calls on
-// the given combination of path and interface.
-//
-// Export returns an error if path is not a valid path name.
-func (conn *Conn) Export(v interface{}, path ObjectPath, iface string) error {
- return conn.ExportWithMap(v, nil, path, iface)
-}
-
-// ExportWithMap works exactly like Export but provides the ability to remap
-// method names (e.g. export a lower-case method).
-//
-// The keys in the map are the real method names (exported on the struct), and
-// the values are the method names to be exported on DBus.
-func (conn *Conn) ExportWithMap(v interface{}, mapping map[string]string, path ObjectPath, iface string) error {
- return conn.exportWithMap(v, mapping, path, iface, false)
-}
-
-// ExportSubtree works exactly like Export but registers the given value for
-// an entire subtree rather under the root path provided.
-//
-// In order to make this useful, one parameter in each of the value's exported
-// methods should be a Message, in which case it will contain the raw message
-// (allowing one to get access to the path that caused the method to be called).
-//
-// Note that more specific export paths take precedence over less specific. For
-// example, a method call using the ObjectPath /foo/bar/baz will call a method
-// exported on /foo/bar before a method exported on /foo.
-func (conn *Conn) ExportSubtree(v interface{}, path ObjectPath, iface string) error {
- return conn.ExportSubtreeWithMap(v, nil, path, iface)
-}
-
-// ExportSubtreeWithMap works exactly like ExportSubtree but provides the
-// ability to remap method names (e.g. export a lower-case method).
-//
-// The keys in the map are the real method names (exported on the struct), and
-// the values are the method names to be exported on DBus.
-func (conn *Conn) ExportSubtreeWithMap(v interface{}, mapping map[string]string, path ObjectPath, iface string) error {
- return conn.exportWithMap(v, mapping, path, iface, true)
-}
-
-// exportWithMap is the worker function for all exports/registrations.
-func (conn *Conn) exportWithMap(v interface{}, mapping map[string]string, path ObjectPath, iface string, includeSubtree bool) error {
- if !path.IsValid() {
- return fmt.Errorf(`dbus: Invalid path name: "%s"`, path)
- }
-
- conn.handlersLck.Lock()
- defer conn.handlersLck.Unlock()
-
- // Remove a previous export if the interface is nil
- if v == nil {
- if _, ok := conn.handlers[path]; ok {
- delete(conn.handlers[path], iface)
- if len(conn.handlers[path]) == 0 {
- delete(conn.handlers, path)
- }
- }
-
- return nil
- }
-
- // If this is the first handler for this path, make a new map to hold all
- // handlers for this path.
- if _, ok := conn.handlers[path]; !ok {
- conn.handlers[path] = make(map[string]exportWithMapping)
- }
-
- // Finally, save this handler
- conn.handlers[path][iface] = exportWithMapping{export: v, mapping: mapping, includeSubtree: includeSubtree}
-
- return nil
-}
-
-// ReleaseName calls org.freedesktop.DBus.ReleaseName and awaits a response.
-func (conn *Conn) ReleaseName(name string) (ReleaseNameReply, error) {
- var r uint32
- err := conn.busObj.Call("org.freedesktop.DBus.ReleaseName", 0, name).Store(&r)
- if err != nil {
- return 0, err
- }
- return ReleaseNameReply(r), nil
-}
-
-// RequestName calls org.freedesktop.DBus.RequestName and awaits a response.
-func (conn *Conn) RequestName(name string, flags RequestNameFlags) (RequestNameReply, error) {
- var r uint32
- err := conn.busObj.Call("org.freedesktop.DBus.RequestName", 0, name, flags).Store(&r)
- if err != nil {
- return 0, err
- }
- return RequestNameReply(r), nil
-}
-
-// ReleaseNameReply is the reply to a ReleaseName call.
-type ReleaseNameReply uint32
-
-const (
- ReleaseNameReplyReleased ReleaseNameReply = 1 + iota
- ReleaseNameReplyNonExistent
- ReleaseNameReplyNotOwner
-)
-
-// RequestNameFlags represents the possible flags for a RequestName call.
-type RequestNameFlags uint32
-
-const (
- NameFlagAllowReplacement RequestNameFlags = 1 << iota
- NameFlagReplaceExisting
- NameFlagDoNotQueue
-)
-
-// RequestNameReply is the reply to a RequestName call.
-type RequestNameReply uint32
-
-const (
- RequestNameReplyPrimaryOwner RequestNameReply = 1 + iota
- RequestNameReplyInQueue
- RequestNameReplyExists
- RequestNameReplyAlreadyOwner
-)
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/homedir.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/homedir.go
deleted file mode 100644
index 0b745f93..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/homedir.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package dbus
-
-import (
- "os"
- "sync"
-)
-
-var (
- homeDir string
- homeDirLock sync.Mutex
-)
-
-func getHomeDir() string {
- homeDirLock.Lock()
- defer homeDirLock.Unlock()
-
- if homeDir != "" {
- return homeDir
- }
-
- homeDir = os.Getenv("HOME")
- if homeDir != "" {
- return homeDir
- }
-
- homeDir = lookupHomeDir()
- return homeDir
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/homedir_dynamic.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/homedir_dynamic.go
deleted file mode 100644
index 2732081e..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/homedir_dynamic.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// +build !static_build
-
-package dbus
-
-import (
- "os/user"
-)
-
-func lookupHomeDir() string {
- u, err := user.Current()
- if err != nil {
- return "/"
- }
- return u.HomeDir
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/homedir_static.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/homedir_static.go
deleted file mode 100644
index b9d9cb55..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/homedir_static.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// +build static_build
-
-package dbus
-
-import (
- "bufio"
- "os"
- "strconv"
- "strings"
-)
-
-func lookupHomeDir() string {
- myUid := os.Getuid()
-
- f, err := os.Open("/etc/passwd")
- if err != nil {
- return "/"
- }
- defer f.Close()
-
- s := bufio.NewScanner(f)
-
- for s.Scan() {
- if err := s.Err(); err != nil {
- break
- }
-
- line := strings.TrimSpace(s.Text())
- if line == "" {
- continue
- }
-
- parts := strings.Split(line, ":")
-
- if len(parts) >= 6 {
- uid, err := strconv.Atoi(parts[2])
- if err == nil && uid == myUid {
- return parts[5]
- }
- }
- }
-
- // Default to / if we can't get a better value
- return "/"
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/introspect/call.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/introspect/call.go
deleted file mode 100644
index 790a23ec..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/introspect/call.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package introspect
-
-import (
- "encoding/xml"
- "github.com/godbus/dbus"
- "strings"
-)
-
-// Call calls org.freedesktop.Introspectable.Introspect on a remote object
-// and returns the introspection data.
-func Call(o dbus.BusObject) (*Node, error) {
- var xmldata string
- var node Node
-
- err := o.Call("org.freedesktop.DBus.Introspectable.Introspect", 0).Store(&xmldata)
- if err != nil {
- return nil, err
- }
- err = xml.NewDecoder(strings.NewReader(xmldata)).Decode(&node)
- if err != nil {
- return nil, err
- }
- if node.Name == "" {
- node.Name = string(o.Path())
- }
- return &node, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/introspect/introspect.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/introspect/introspect.go
deleted file mode 100644
index b06c3f1c..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/introspect/introspect.go
+++ /dev/null
@@ -1,86 +0,0 @@
-// Package introspect provides some utilities for dealing with the DBus
-// introspection format.
-package introspect
-
-import "encoding/xml"
-
-// The introspection data for the org.freedesktop.DBus.Introspectable interface.
-var IntrospectData = Interface{
- Name: "org.freedesktop.DBus.Introspectable",
- Methods: []Method{
- {
- Name: "Introspect",
- Args: []Arg{
- {"out", "s", "out"},
- },
- },
- },
-}
-
-// XML document type declaration of the introspection format version 1.0
-const IntrospectDeclarationString = `
-
-`
-
-// The introspection data for the org.freedesktop.DBus.Introspectable interface,
-// as a string.
-const IntrospectDataString = `
-
-
-
-
-
-`
-
-// Node is the root element of an introspection.
-type Node struct {
- XMLName xml.Name `xml:"node"`
- Name string `xml:"name,attr,omitempty"`
- Interfaces []Interface `xml:"interface"`
- Children []Node `xml:"node,omitempty"`
-}
-
-// Interface describes a DBus interface that is available on the message bus.
-type Interface struct {
- Name string `xml:"name,attr"`
- Methods []Method `xml:"method"`
- Signals []Signal `xml:"signal"`
- Properties []Property `xml:"property"`
- Annotations []Annotation `xml:"annotation"`
-}
-
-// Method describes a Method on an Interface as retured by an introspection.
-type Method struct {
- Name string `xml:"name,attr"`
- Args []Arg `xml:"arg"`
- Annotations []Annotation `xml:"annotation"`
-}
-
-// Signal describes a Signal emitted on an Interface.
-type Signal struct {
- Name string `xml:"name,attr"`
- Args []Arg `xml:"arg"`
- Annotations []Annotation `xml:"annotation"`
-}
-
-// Property describes a property of an Interface.
-type Property struct {
- Name string `xml:"name,attr"`
- Type string `xml:"type,attr"`
- Access string `xml:"access,attr"`
- Annotations []Annotation `xml:"annotation"`
-}
-
-// Arg represents an argument of a method or a signal.
-type Arg struct {
- Name string `xml:"name,attr,omitempty"`
- Type string `xml:"type,attr"`
- Direction string `xml:"direction,attr,omitempty"`
-}
-
-// Annotation is an annotation in the introspection format.
-type Annotation struct {
- Name string `xml:"name,attr"`
- Value string `xml:"value,attr"`
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/introspect/introspectable.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/introspect/introspectable.go
deleted file mode 100644
index 2f16690b..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/introspect/introspectable.go
+++ /dev/null
@@ -1,76 +0,0 @@
-package introspect
-
-import (
- "encoding/xml"
- "github.com/godbus/dbus"
- "reflect"
- "strings"
-)
-
-// Introspectable implements org.freedesktop.Introspectable.
-//
-// You can create it by converting the XML-formatted introspection data from a
-// string to an Introspectable or call NewIntrospectable with a Node. Then,
-// export it as org.freedesktop.Introspectable on you object.
-type Introspectable string
-
-// NewIntrospectable returns an Introspectable that returns the introspection
-// data that corresponds to the given Node. If n.Interfaces doesn't contain the
-// data for org.freedesktop.DBus.Introspectable, it is added automatically.
-func NewIntrospectable(n *Node) Introspectable {
- found := false
- for _, v := range n.Interfaces {
- if v.Name == "org.freedesktop.DBus.Introspectable" {
- found = true
- break
- }
- }
- if !found {
- n.Interfaces = append(n.Interfaces, IntrospectData)
- }
- b, err := xml.Marshal(n)
- if err != nil {
- panic(err)
- }
- return Introspectable(strings.TrimSpace(IntrospectDeclarationString) + string(b))
-}
-
-// Introspect implements org.freedesktop.Introspectable.Introspect.
-func (i Introspectable) Introspect() (string, *dbus.Error) {
- return string(i), nil
-}
-
-// Methods returns the description of the methods of v. This can be used to
-// create a Node which can be passed to NewIntrospectable.
-func Methods(v interface{}) []Method {
- t := reflect.TypeOf(v)
- ms := make([]Method, 0, t.NumMethod())
- for i := 0; i < t.NumMethod(); i++ {
- if t.Method(i).PkgPath != "" {
- continue
- }
- mt := t.Method(i).Type
- if mt.NumOut() == 0 ||
- mt.Out(mt.NumOut()-1) != reflect.TypeOf(&dbus.Error{}) {
-
- continue
- }
- var m Method
- m.Name = t.Method(i).Name
- m.Args = make([]Arg, 0, mt.NumIn()+mt.NumOut()-2)
- for j := 1; j < mt.NumIn(); j++ {
- if mt.In(j) != reflect.TypeOf((*dbus.Sender)(nil)).Elem() &&
- mt.In(j) != reflect.TypeOf((*dbus.Message)(nil)).Elem() {
- arg := Arg{"", dbus.SignatureOfType(mt.In(j)).String(), "in"}
- m.Args = append(m.Args, arg)
- }
- }
- for j := 0; j < mt.NumOut()-1; j++ {
- arg := Arg{"", dbus.SignatureOfType(mt.Out(j)).String(), "out"}
- m.Args = append(m.Args, arg)
- }
- m.Annotations = make([]Annotation, 0)
- ms = append(ms, m)
- }
- return ms
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/message.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/message.go
deleted file mode 100644
index 075d6e38..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/message.go
+++ /dev/null
@@ -1,346 +0,0 @@
-package dbus
-
-import (
- "bytes"
- "encoding/binary"
- "errors"
- "io"
- "reflect"
- "strconv"
-)
-
-const protoVersion byte = 1
-
-// Flags represents the possible flags of a D-Bus message.
-type Flags byte
-
-const (
- // FlagNoReplyExpected signals that the message is not expected to generate
- // a reply. If this flag is set on outgoing messages, any possible reply
- // will be discarded.
- FlagNoReplyExpected Flags = 1 << iota
- // FlagNoAutoStart signals that the message bus should not automatically
- // start an application when handling this message.
- FlagNoAutoStart
-)
-
-// Type represents the possible types of a D-Bus message.
-type Type byte
-
-const (
- TypeMethodCall Type = 1 + iota
- TypeMethodReply
- TypeError
- TypeSignal
- typeMax
-)
-
-func (t Type) String() string {
- switch t {
- case TypeMethodCall:
- return "method call"
- case TypeMethodReply:
- return "reply"
- case TypeError:
- return "error"
- case TypeSignal:
- return "signal"
- }
- return "invalid"
-}
-
-// HeaderField represents the possible byte codes for the headers
-// of a D-Bus message.
-type HeaderField byte
-
-const (
- FieldPath HeaderField = 1 + iota
- FieldInterface
- FieldMember
- FieldErrorName
- FieldReplySerial
- FieldDestination
- FieldSender
- FieldSignature
- FieldUnixFDs
- fieldMax
-)
-
-// An InvalidMessageError describes the reason why a D-Bus message is regarded as
-// invalid.
-type InvalidMessageError string
-
-func (e InvalidMessageError) Error() string {
- return "dbus: invalid message: " + string(e)
-}
-
-// fieldType are the types of the various header fields.
-var fieldTypes = [fieldMax]reflect.Type{
- FieldPath: objectPathType,
- FieldInterface: stringType,
- FieldMember: stringType,
- FieldErrorName: stringType,
- FieldReplySerial: uint32Type,
- FieldDestination: stringType,
- FieldSender: stringType,
- FieldSignature: signatureType,
- FieldUnixFDs: uint32Type,
-}
-
-// requiredFields lists the header fields that are required by the different
-// message types.
-var requiredFields = [typeMax][]HeaderField{
- TypeMethodCall: {FieldPath, FieldMember},
- TypeMethodReply: {FieldReplySerial},
- TypeError: {FieldErrorName, FieldReplySerial},
- TypeSignal: {FieldPath, FieldInterface, FieldMember},
-}
-
-// Message represents a single D-Bus message.
-type Message struct {
- Type
- Flags
- Headers map[HeaderField]Variant
- Body []interface{}
-
- serial uint32
-}
-
-type header struct {
- Field byte
- Variant
-}
-
-// DecodeMessage tries to decode a single message in the D-Bus wire format
-// from the given reader. The byte order is figured out from the first byte.
-// The possibly returned error can be an error of the underlying reader, an
-// InvalidMessageError or a FormatError.
-func DecodeMessage(rd io.Reader) (msg *Message, err error) {
- var order binary.ByteOrder
- var hlength, length uint32
- var typ, flags, proto byte
- var headers []header
-
- b := make([]byte, 1)
- _, err = rd.Read(b)
- if err != nil {
- return
- }
- switch b[0] {
- case 'l':
- order = binary.LittleEndian
- case 'B':
- order = binary.BigEndian
- default:
- return nil, InvalidMessageError("invalid byte order")
- }
-
- dec := newDecoder(rd, order)
- dec.pos = 1
-
- msg = new(Message)
- vs, err := dec.Decode(Signature{"yyyuu"})
- if err != nil {
- return nil, err
- }
- if err = Store(vs, &typ, &flags, &proto, &length, &msg.serial); err != nil {
- return nil, err
- }
- msg.Type = Type(typ)
- msg.Flags = Flags(flags)
-
- // get the header length separately because we need it later
- b = make([]byte, 4)
- _, err = io.ReadFull(rd, b)
- if err != nil {
- return nil, err
- }
- binary.Read(bytes.NewBuffer(b), order, &hlength)
- if hlength+length+16 > 1<<27 {
- return nil, InvalidMessageError("message is too long")
- }
- dec = newDecoder(io.MultiReader(bytes.NewBuffer(b), rd), order)
- dec.pos = 12
- vs, err = dec.Decode(Signature{"a(yv)"})
- if err != nil {
- return nil, err
- }
- if err = Store(vs, &headers); err != nil {
- return nil, err
- }
-
- msg.Headers = make(map[HeaderField]Variant)
- for _, v := range headers {
- msg.Headers[HeaderField(v.Field)] = v.Variant
- }
-
- dec.align(8)
- body := make([]byte, int(length))
- if length != 0 {
- _, err := io.ReadFull(rd, body)
- if err != nil {
- return nil, err
- }
- }
-
- if err = msg.IsValid(); err != nil {
- return nil, err
- }
- sig, _ := msg.Headers[FieldSignature].value.(Signature)
- if sig.str != "" {
- buf := bytes.NewBuffer(body)
- dec = newDecoder(buf, order)
- vs, err := dec.Decode(sig)
- if err != nil {
- return nil, err
- }
- msg.Body = vs
- }
-
- return
-}
-
-// EncodeTo encodes and sends a message to the given writer. The byte order must
-// be either binary.LittleEndian or binary.BigEndian. If the message is not
-// valid or an error occurs when writing, an error is returned.
-func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) error {
- if err := msg.IsValid(); err != nil {
- return err
- }
- var vs [7]interface{}
- switch order {
- case binary.LittleEndian:
- vs[0] = byte('l')
- case binary.BigEndian:
- vs[0] = byte('B')
- default:
- return errors.New("dbus: invalid byte order")
- }
- body := new(bytes.Buffer)
- enc := newEncoder(body, order)
- if len(msg.Body) != 0 {
- enc.Encode(msg.Body...)
- }
- vs[1] = msg.Type
- vs[2] = msg.Flags
- vs[3] = protoVersion
- vs[4] = uint32(len(body.Bytes()))
- vs[5] = msg.serial
- headers := make([]header, 0, len(msg.Headers))
- for k, v := range msg.Headers {
- headers = append(headers, header{byte(k), v})
- }
- vs[6] = headers
- var buf bytes.Buffer
- enc = newEncoder(&buf, order)
- enc.Encode(vs[:]...)
- enc.align(8)
- body.WriteTo(&buf)
- if buf.Len() > 1<<27 {
- return InvalidMessageError("message is too long")
- }
- if _, err := buf.WriteTo(out); err != nil {
- return err
- }
- return nil
-}
-
-// IsValid checks whether msg is a valid message and returns an
-// InvalidMessageError if it is not.
-func (msg *Message) IsValid() error {
- if msg.Flags & ^(FlagNoAutoStart|FlagNoReplyExpected) != 0 {
- return InvalidMessageError("invalid flags")
- }
- if msg.Type == 0 || msg.Type >= typeMax {
- return InvalidMessageError("invalid message type")
- }
- for k, v := range msg.Headers {
- if k == 0 || k >= fieldMax {
- return InvalidMessageError("invalid header")
- }
- if reflect.TypeOf(v.value) != fieldTypes[k] {
- return InvalidMessageError("invalid type of header field")
- }
- }
- for _, v := range requiredFields[msg.Type] {
- if _, ok := msg.Headers[v]; !ok {
- return InvalidMessageError("missing required header")
- }
- }
- if path, ok := msg.Headers[FieldPath]; ok {
- if !path.value.(ObjectPath).IsValid() {
- return InvalidMessageError("invalid path name")
- }
- }
- if iface, ok := msg.Headers[FieldInterface]; ok {
- if !isValidInterface(iface.value.(string)) {
- return InvalidMessageError("invalid interface name")
- }
- }
- if member, ok := msg.Headers[FieldMember]; ok {
- if !isValidMember(member.value.(string)) {
- return InvalidMessageError("invalid member name")
- }
- }
- if errname, ok := msg.Headers[FieldErrorName]; ok {
- if !isValidInterface(errname.value.(string)) {
- return InvalidMessageError("invalid error name")
- }
- }
- if len(msg.Body) != 0 {
- if _, ok := msg.Headers[FieldSignature]; !ok {
- return InvalidMessageError("missing signature")
- }
- }
- return nil
-}
-
-// Serial returns the message's serial number. The returned value is only valid
-// for messages received by eavesdropping.
-func (msg *Message) Serial() uint32 {
- return msg.serial
-}
-
-// String returns a string representation of a message similar to the format of
-// dbus-monitor.
-func (msg *Message) String() string {
- if err := msg.IsValid(); err != nil {
- return ""
- }
- s := msg.Type.String()
- if v, ok := msg.Headers[FieldSender]; ok {
- s += " from " + v.value.(string)
- }
- if v, ok := msg.Headers[FieldDestination]; ok {
- s += " to " + v.value.(string)
- }
- s += " serial " + strconv.FormatUint(uint64(msg.serial), 10)
- if v, ok := msg.Headers[FieldReplySerial]; ok {
- s += " reply_serial " + strconv.FormatUint(uint64(v.value.(uint32)), 10)
- }
- if v, ok := msg.Headers[FieldUnixFDs]; ok {
- s += " unixfds " + strconv.FormatUint(uint64(v.value.(uint32)), 10)
- }
- if v, ok := msg.Headers[FieldPath]; ok {
- s += " path " + string(v.value.(ObjectPath))
- }
- if v, ok := msg.Headers[FieldInterface]; ok {
- s += " interface " + v.value.(string)
- }
- if v, ok := msg.Headers[FieldErrorName]; ok {
- s += " error " + v.value.(string)
- }
- if v, ok := msg.Headers[FieldMember]; ok {
- s += " member " + v.value.(string)
- }
- if len(msg.Body) != 0 {
- s += "\n"
- }
- for i, v := range msg.Body {
- s += " " + MakeVariant(v).String()
- if i != len(msg.Body)-1 {
- s += "\n"
- }
- }
- return s
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/object.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/object.go
deleted file mode 100644
index 7ef45da4..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/object.go
+++ /dev/null
@@ -1,126 +0,0 @@
-package dbus
-
-import (
- "errors"
- "strings"
-)
-
-// BusObject is the interface of a remote object on which methods can be
-// invoked.
-type BusObject interface {
- Call(method string, flags Flags, args ...interface{}) *Call
- Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call
- GetProperty(p string) (Variant, error)
- Destination() string
- Path() ObjectPath
-}
-
-// Object represents a remote object on which methods can be invoked.
-type Object struct {
- conn *Conn
- dest string
- path ObjectPath
-}
-
-// Call calls a method with (*Object).Go and waits for its reply.
-func (o *Object) Call(method string, flags Flags, args ...interface{}) *Call {
- return <-o.Go(method, flags, make(chan *Call, 1), args...).Done
-}
-
-// Go calls a method with the given arguments asynchronously. It returns a
-// Call structure representing this method call. The passed channel will
-// return the same value once the call is done. If ch is nil, a new channel
-// will be allocated. Otherwise, ch has to be buffered or Go will panic.
-//
-// If the flags include FlagNoReplyExpected, ch is ignored and a Call structure
-// is returned of which only the Err member is valid.
-//
-// If the method parameter contains a dot ('.'), the part before the last dot
-// specifies the interface on which the method is called.
-func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call {
- iface := ""
- i := strings.LastIndex(method, ".")
- if i != -1 {
- iface = method[:i]
- }
- method = method[i+1:]
- msg := new(Message)
- msg.Type = TypeMethodCall
- msg.serial = o.conn.getSerial()
- msg.Flags = flags & (FlagNoAutoStart | FlagNoReplyExpected)
- msg.Headers = make(map[HeaderField]Variant)
- msg.Headers[FieldPath] = MakeVariant(o.path)
- msg.Headers[FieldDestination] = MakeVariant(o.dest)
- msg.Headers[FieldMember] = MakeVariant(method)
- if iface != "" {
- msg.Headers[FieldInterface] = MakeVariant(iface)
- }
- msg.Body = args
- if len(args) > 0 {
- msg.Headers[FieldSignature] = MakeVariant(SignatureOf(args...))
- }
- if msg.Flags&FlagNoReplyExpected == 0 {
- if ch == nil {
- ch = make(chan *Call, 10)
- } else if cap(ch) == 0 {
- panic("dbus: unbuffered channel passed to (*Object).Go")
- }
- call := &Call{
- Destination: o.dest,
- Path: o.path,
- Method: method,
- Args: args,
- Done: ch,
- }
- o.conn.callsLck.Lock()
- o.conn.calls[msg.serial] = call
- o.conn.callsLck.Unlock()
- o.conn.outLck.RLock()
- if o.conn.closed {
- call.Err = ErrClosed
- call.Done <- call
- } else {
- o.conn.out <- msg
- }
- o.conn.outLck.RUnlock()
- return call
- }
- o.conn.outLck.RLock()
- defer o.conn.outLck.RUnlock()
- if o.conn.closed {
- return &Call{Err: ErrClosed}
- }
- o.conn.out <- msg
- return &Call{Err: nil}
-}
-
-// GetProperty calls org.freedesktop.DBus.Properties.GetProperty on the given
-// object. The property name must be given in interface.member notation.
-func (o *Object) GetProperty(p string) (Variant, error) {
- idx := strings.LastIndex(p, ".")
- if idx == -1 || idx+1 == len(p) {
- return Variant{}, errors.New("dbus: invalid property " + p)
- }
-
- iface := p[:idx]
- prop := p[idx+1:]
-
- result := Variant{}
- err := o.Call("org.freedesktop.DBus.Properties.Get", 0, iface, prop).Store(&result)
-
- if err != nil {
- return Variant{}, err
- }
-
- return result, nil
-}
-
-// Destination returns the destination that calls on o are sent to.
-func (o *Object) Destination() string {
- return o.dest
-}
-
-// Path returns the path that calls on o are sent to.
-func (o *Object) Path() ObjectPath {
- return o.path
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/prop/prop.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/prop/prop.go
deleted file mode 100644
index 834a1fa8..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/prop/prop.go
+++ /dev/null
@@ -1,264 +0,0 @@
-// Package prop provides the Properties struct which can be used to implement
-// org.freedesktop.DBus.Properties.
-package prop
-
-import (
- "github.com/godbus/dbus"
- "github.com/godbus/dbus/introspect"
- "sync"
-)
-
-// EmitType controls how org.freedesktop.DBus.Properties.PropertiesChanged is
-// emitted for a property. If it is EmitTrue, the signal is emitted. If it is
-// EmitInvalidates, the signal is also emitted, but the new value of the property
-// is not disclosed.
-type EmitType byte
-
-const (
- EmitFalse EmitType = iota
- EmitTrue
- EmitInvalidates
-)
-
-// ErrIfaceNotFound is the error returned to peers who try to access properties
-// on interfaces that aren't found.
-var ErrIfaceNotFound = dbus.NewError("org.freedesktop.DBus.Properties.Error.InterfaceNotFound", nil)
-
-// ErrPropNotFound is the error returned to peers trying to access properties
-// that aren't found.
-var ErrPropNotFound = dbus.NewError("org.freedesktop.DBus.Properties.Error.PropertyNotFound", nil)
-
-// ErrReadOnly is the error returned to peers trying to set a read-only
-// property.
-var ErrReadOnly = dbus.NewError("org.freedesktop.DBus.Properties.Error.ReadOnly", nil)
-
-// ErrInvalidArg is returned to peers if the type of the property that is being
-// changed and the argument don't match.
-var ErrInvalidArg = dbus.NewError("org.freedesktop.DBus.Properties.Error.InvalidArg", nil)
-
-// The introspection data for the org.freedesktop.DBus.Properties interface.
-var IntrospectData = introspect.Interface{
- Name: "org.freedesktop.DBus.Properties",
- Methods: []introspect.Method{
- {
- Name: "Get",
- Args: []introspect.Arg{
- {"interface", "s", "in"},
- {"property", "s", "in"},
- {"value", "v", "out"},
- },
- },
- {
- Name: "GetAll",
- Args: []introspect.Arg{
- {"interface", "s", "in"},
- {"props", "a{sv}", "out"},
- },
- },
- {
- Name: "Set",
- Args: []introspect.Arg{
- {"interface", "s", "in"},
- {"property", "s", "in"},
- {"value", "v", "in"},
- },
- },
- },
- Signals: []introspect.Signal{
- {
- Name: "PropertiesChanged",
- Args: []introspect.Arg{
- {"interface", "s", "out"},
- {"changed_properties", "a{sv}", "out"},
- {"invalidates_properties", "as", "out"},
- },
- },
- },
-}
-
-// The introspection data for the org.freedesktop.DBus.Properties interface, as
-// a string.
-const IntrospectDataString = `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-`
-
-// Prop represents a single property. It is used for creating a Properties
-// value.
-type Prop struct {
- // Initial value. Must be a DBus-representable type.
- Value interface{}
-
- // If true, the value can be modified by calls to Set.
- Writable bool
-
- // Controls how org.freedesktop.DBus.Properties.PropertiesChanged is
- // emitted if this property changes.
- Emit EmitType
-
- // If not nil, anytime this property is changed by Set, this function is
- // called with an appropiate Change as its argument. If the returned error
- // is not nil, it is sent back to the caller of Set and the property is not
- // changed.
- Callback func(*Change) *dbus.Error
-}
-
-// Change represents a change of a property by a call to Set.
-type Change struct {
- Props *Properties
- Iface string
- Name string
- Value interface{}
-}
-
-// Properties is a set of values that can be made available to the message bus
-// using the org.freedesktop.DBus.Properties interface. It is safe for
-// concurrent use by multiple goroutines.
-type Properties struct {
- m map[string]map[string]*Prop
- mut sync.RWMutex
- conn *dbus.Conn
- path dbus.ObjectPath
-}
-
-// New returns a new Properties structure that manages the given properties.
-// The key for the first-level map of props is the name of the interface; the
-// second-level key is the name of the property. The returned structure will be
-// exported as org.freedesktop.DBus.Properties on path.
-func New(conn *dbus.Conn, path dbus.ObjectPath, props map[string]map[string]*Prop) *Properties {
- p := &Properties{m: props, conn: conn, path: path}
- conn.Export(p, path, "org.freedesktop.DBus.Properties")
- return p
-}
-
-// Get implements org.freedesktop.DBus.Properties.Get.
-func (p *Properties) Get(iface, property string) (dbus.Variant, *dbus.Error) {
- p.mut.RLock()
- defer p.mut.RUnlock()
- m, ok := p.m[iface]
- if !ok {
- return dbus.Variant{}, ErrIfaceNotFound
- }
- prop, ok := m[property]
- if !ok {
- return dbus.Variant{}, ErrPropNotFound
- }
- return dbus.MakeVariant(prop.Value), nil
-}
-
-// GetAll implements org.freedesktop.DBus.Properties.GetAll.
-func (p *Properties) GetAll(iface string) (map[string]dbus.Variant, *dbus.Error) {
- p.mut.RLock()
- defer p.mut.RUnlock()
- m, ok := p.m[iface]
- if !ok {
- return nil, ErrIfaceNotFound
- }
- rm := make(map[string]dbus.Variant, len(m))
- for k, v := range m {
- rm[k] = dbus.MakeVariant(v.Value)
- }
- return rm, nil
-}
-
-// GetMust returns the value of the given property and panics if either the
-// interface or the property name are invalid.
-func (p *Properties) GetMust(iface, property string) interface{} {
- p.mut.RLock()
- defer p.mut.RUnlock()
- return p.m[iface][property].Value
-}
-
-// Introspection returns the introspection data that represents the properties
-// of iface.
-func (p *Properties) Introspection(iface string) []introspect.Property {
- p.mut.RLock()
- defer p.mut.RUnlock()
- m := p.m[iface]
- s := make([]introspect.Property, 0, len(m))
- for k, v := range m {
- p := introspect.Property{Name: k, Type: dbus.SignatureOf(v.Value).String()}
- if v.Writable {
- p.Access = "readwrite"
- } else {
- p.Access = "read"
- }
- s = append(s, p)
- }
- return s
-}
-
-// set sets the given property and emits PropertyChanged if appropiate. p.mut
-// must already be locked.
-func (p *Properties) set(iface, property string, v interface{}) {
- prop := p.m[iface][property]
- prop.Value = v
- switch prop.Emit {
- case EmitFalse:
- // do nothing
- case EmitInvalidates:
- p.conn.Emit(p.path, "org.freedesktop.DBus.Properties.PropertiesChanged",
- iface, map[string]dbus.Variant{}, []string{property})
- case EmitTrue:
- p.conn.Emit(p.path, "org.freedesktop.DBus.Properties.PropertiesChanged",
- iface, map[string]dbus.Variant{property: dbus.MakeVariant(v)},
- []string{})
- default:
- panic("invalid value for EmitType")
- }
-}
-
-// Set implements org.freedesktop.Properties.Set.
-func (p *Properties) Set(iface, property string, newv dbus.Variant) *dbus.Error {
- p.mut.Lock()
- defer p.mut.Unlock()
- m, ok := p.m[iface]
- if !ok {
- return ErrIfaceNotFound
- }
- prop, ok := m[property]
- if !ok {
- return ErrPropNotFound
- }
- if !prop.Writable {
- return ErrReadOnly
- }
- if newv.Signature() != dbus.SignatureOf(prop.Value) {
- return ErrInvalidArg
- }
- if prop.Callback != nil {
- err := prop.Callback(&Change{p, iface, property, newv.Value()})
- if err != nil {
- return err
- }
- }
- p.set(iface, property, newv.Value())
- return nil
-}
-
-// SetMust sets the value of the given property and panics if the interface or
-// the property name are invalid.
-func (p *Properties) SetMust(iface, property string, v interface{}) {
- p.mut.Lock()
- p.set(iface, property, v)
- p.mut.Unlock()
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/sig.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/sig.go
deleted file mode 100644
index f45b53ce..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/sig.go
+++ /dev/null
@@ -1,257 +0,0 @@
-package dbus
-
-import (
- "fmt"
- "reflect"
- "strings"
-)
-
-var sigToType = map[byte]reflect.Type{
- 'y': byteType,
- 'b': boolType,
- 'n': int16Type,
- 'q': uint16Type,
- 'i': int32Type,
- 'u': uint32Type,
- 'x': int64Type,
- 't': uint64Type,
- 'd': float64Type,
- 's': stringType,
- 'g': signatureType,
- 'o': objectPathType,
- 'v': variantType,
- 'h': unixFDIndexType,
-}
-
-// Signature represents a correct type signature as specified by the D-Bus
-// specification. The zero value represents the empty signature, "".
-type Signature struct {
- str string
-}
-
-// SignatureOf returns the concatenation of all the signatures of the given
-// values. It panics if one of them is not representable in D-Bus.
-func SignatureOf(vs ...interface{}) Signature {
- var s string
- for _, v := range vs {
- s += getSignature(reflect.TypeOf(v))
- }
- return Signature{s}
-}
-
-// SignatureOfType returns the signature of the given type. It panics if the
-// type is not representable in D-Bus.
-func SignatureOfType(t reflect.Type) Signature {
- return Signature{getSignature(t)}
-}
-
-// getSignature returns the signature of the given type and panics on unknown types.
-func getSignature(t reflect.Type) string {
- // handle simple types first
- switch t.Kind() {
- case reflect.Uint8:
- return "y"
- case reflect.Bool:
- return "b"
- case reflect.Int16:
- return "n"
- case reflect.Uint16:
- return "q"
- case reflect.Int32:
- if t == unixFDType {
- return "h"
- }
- return "i"
- case reflect.Uint32:
- if t == unixFDIndexType {
- return "h"
- }
- return "u"
- case reflect.Int64:
- return "x"
- case reflect.Uint64:
- return "t"
- case reflect.Float64:
- return "d"
- case reflect.Ptr:
- return getSignature(t.Elem())
- case reflect.String:
- if t == objectPathType {
- return "o"
- }
- return "s"
- case reflect.Struct:
- if t == variantType {
- return "v"
- } else if t == signatureType {
- return "g"
- }
- var s string
- for i := 0; i < t.NumField(); i++ {
- field := t.Field(i)
- if field.PkgPath == "" && field.Tag.Get("dbus") != "-" {
- s += getSignature(t.Field(i).Type)
- }
- }
- return "(" + s + ")"
- case reflect.Array, reflect.Slice:
- return "a" + getSignature(t.Elem())
- case reflect.Map:
- if !isKeyType(t.Key()) {
- panic(InvalidTypeError{t})
- }
- return "a{" + getSignature(t.Key()) + getSignature(t.Elem()) + "}"
- }
- panic(InvalidTypeError{t})
-}
-
-// ParseSignature returns the signature represented by this string, or a
-// SignatureError if the string is not a valid signature.
-func ParseSignature(s string) (sig Signature, err error) {
- if len(s) == 0 {
- return
- }
- if len(s) > 255 {
- return Signature{""}, SignatureError{s, "too long"}
- }
- sig.str = s
- for err == nil && len(s) != 0 {
- err, s = validSingle(s, 0)
- }
- if err != nil {
- sig = Signature{""}
- }
-
- return
-}
-
-// ParseSignatureMust behaves like ParseSignature, except that it panics if s
-// is not valid.
-func ParseSignatureMust(s string) Signature {
- sig, err := ParseSignature(s)
- if err != nil {
- panic(err)
- }
- return sig
-}
-
-// Empty retruns whether the signature is the empty signature.
-func (s Signature) Empty() bool {
- return s.str == ""
-}
-
-// Single returns whether the signature represents a single, complete type.
-func (s Signature) Single() bool {
- err, r := validSingle(s.str, 0)
- return err != nil && r == ""
-}
-
-// String returns the signature's string representation.
-func (s Signature) String() string {
- return s.str
-}
-
-// A SignatureError indicates that a signature passed to a function or received
-// on a connection is not a valid signature.
-type SignatureError struct {
- Sig string
- Reason string
-}
-
-func (e SignatureError) Error() string {
- return fmt.Sprintf("dbus: invalid signature: %q (%s)", e.Sig, e.Reason)
-}
-
-// Try to read a single type from this string. If it was successfull, err is nil
-// and rem is the remaining unparsed part. Otherwise, err is a non-nil
-// SignatureError and rem is "". depth is the current recursion depth which may
-// not be greater than 64 and should be given as 0 on the first call.
-func validSingle(s string, depth int) (err error, rem string) {
- if s == "" {
- return SignatureError{Sig: s, Reason: "empty signature"}, ""
- }
- if depth > 64 {
- return SignatureError{Sig: s, Reason: "container nesting too deep"}, ""
- }
- switch s[0] {
- case 'y', 'b', 'n', 'q', 'i', 'u', 'x', 't', 'd', 's', 'g', 'o', 'v', 'h':
- return nil, s[1:]
- case 'a':
- if len(s) > 1 && s[1] == '{' {
- i := findMatching(s[1:], '{', '}')
- if i == -1 {
- return SignatureError{Sig: s, Reason: "unmatched '{'"}, ""
- }
- i++
- rem = s[i+1:]
- s = s[2:i]
- if err, _ = validSingle(s[:1], depth+1); err != nil {
- return err, ""
- }
- err, nr := validSingle(s[1:], depth+1)
- if err != nil {
- return err, ""
- }
- if nr != "" {
- return SignatureError{Sig: s, Reason: "too many types in dict"}, ""
- }
- return nil, rem
- }
- return validSingle(s[1:], depth+1)
- case '(':
- i := findMatching(s, '(', ')')
- if i == -1 {
- return SignatureError{Sig: s, Reason: "unmatched ')'"}, ""
- }
- rem = s[i+1:]
- s = s[1:i]
- for err == nil && s != "" {
- err, s = validSingle(s, depth+1)
- }
- if err != nil {
- rem = ""
- }
- return
- }
- return SignatureError{Sig: s, Reason: "invalid type character"}, ""
-}
-
-func findMatching(s string, left, right rune) int {
- n := 0
- for i, v := range s {
- if v == left {
- n++
- } else if v == right {
- n--
- }
- if n == 0 {
- return i
- }
- }
- return -1
-}
-
-// typeFor returns the type of the given signature. It ignores any left over
-// characters and panics if s doesn't start with a valid type signature.
-func typeFor(s string) (t reflect.Type) {
- err, _ := validSingle(s, 0)
- if err != nil {
- panic(err)
- }
-
- if t, ok := sigToType[s[0]]; ok {
- return t
- }
- switch s[0] {
- case 'a':
- if s[1] == '{' {
- i := strings.LastIndex(s, "}")
- t = reflect.MapOf(sigToType[s[2]], typeFor(s[3:i]))
- } else {
- t = reflect.SliceOf(typeFor(s[1:]))
- }
- case '(':
- t = interfacesType
- }
- return
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/transport_darwin.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/transport_darwin.go
deleted file mode 100644
index 1bba0d6b..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/transport_darwin.go
+++ /dev/null
@@ -1,6 +0,0 @@
-package dbus
-
-func (t *unixTransport) SendNullByte() error {
- _, err := t.Write([]byte{0})
- return err
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/transport_generic.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/transport_generic.go
deleted file mode 100644
index 46f8f49d..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/transport_generic.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package dbus
-
-import (
- "encoding/binary"
- "errors"
- "io"
-)
-
-type genericTransport struct {
- io.ReadWriteCloser
-}
-
-func (t genericTransport) SendNullByte() error {
- _, err := t.Write([]byte{0})
- return err
-}
-
-func (t genericTransport) SupportsUnixFDs() bool {
- return false
-}
-
-func (t genericTransport) EnableUnixFDs() {}
-
-func (t genericTransport) ReadMessage() (*Message, error) {
- return DecodeMessage(t)
-}
-
-func (t genericTransport) SendMessage(msg *Message) error {
- for _, v := range msg.Body {
- if _, ok := v.(UnixFD); ok {
- return errors.New("dbus: unix fd passing not enabled")
- }
- }
- return msg.EncodeTo(t, binary.LittleEndian)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/transport_unix.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/transport_unix.go
deleted file mode 100644
index 3fafeabb..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/transport_unix.go
+++ /dev/null
@@ -1,196 +0,0 @@
-//+build !windows
-
-package dbus
-
-import (
- "bytes"
- "encoding/binary"
- "errors"
- "io"
- "net"
- "syscall"
-)
-
-type oobReader struct {
- conn *net.UnixConn
- oob []byte
- buf [4096]byte
-}
-
-func (o *oobReader) Read(b []byte) (n int, err error) {
- n, oobn, flags, _, err := o.conn.ReadMsgUnix(b, o.buf[:])
- if err != nil {
- return n, err
- }
- if flags&syscall.MSG_CTRUNC != 0 {
- return n, errors.New("dbus: control data truncated (too many fds received)")
- }
- o.oob = append(o.oob, o.buf[:oobn]...)
- return n, nil
-}
-
-type unixTransport struct {
- *net.UnixConn
- hasUnixFDs bool
-}
-
-func newUnixTransport(keys string) (transport, error) {
- var err error
-
- t := new(unixTransport)
- abstract := getKey(keys, "abstract")
- path := getKey(keys, "path")
- switch {
- case abstract == "" && path == "":
- return nil, errors.New("dbus: invalid address (neither path nor abstract set)")
- case abstract != "" && path == "":
- t.UnixConn, err = net.DialUnix("unix", nil, &net.UnixAddr{Name: "@" + abstract, Net: "unix"})
- if err != nil {
- return nil, err
- }
- return t, nil
- case abstract == "" && path != "":
- t.UnixConn, err = net.DialUnix("unix", nil, &net.UnixAddr{Name: path, Net: "unix"})
- if err != nil {
- return nil, err
- }
- return t, nil
- default:
- return nil, errors.New("dbus: invalid address (both path and abstract set)")
- }
-}
-
-func init() {
- transports["unix"] = newUnixTransport
-}
-
-func (t *unixTransport) EnableUnixFDs() {
- t.hasUnixFDs = true
-}
-
-func (t *unixTransport) ReadMessage() (*Message, error) {
- var (
- blen, hlen uint32
- csheader [16]byte
- headers []header
- order binary.ByteOrder
- unixfds uint32
- )
- // To be sure that all bytes of out-of-band data are read, we use a special
- // reader that uses ReadUnix on the underlying connection instead of Read
- // and gathers the out-of-band data in a buffer.
- rd := &oobReader{conn: t.UnixConn}
- // read the first 16 bytes (the part of the header that has a constant size),
- // from which we can figure out the length of the rest of the message
- if _, err := io.ReadFull(rd, csheader[:]); err != nil {
- return nil, err
- }
- switch csheader[0] {
- case 'l':
- order = binary.LittleEndian
- case 'B':
- order = binary.BigEndian
- default:
- return nil, InvalidMessageError("invalid byte order")
- }
- // csheader[4:8] -> length of message body, csheader[12:16] -> length of
- // header fields (without alignment)
- binary.Read(bytes.NewBuffer(csheader[4:8]), order, &blen)
- binary.Read(bytes.NewBuffer(csheader[12:]), order, &hlen)
- if hlen%8 != 0 {
- hlen += 8 - (hlen % 8)
- }
-
- // decode headers and look for unix fds
- headerdata := make([]byte, hlen+4)
- copy(headerdata, csheader[12:])
- if _, err := io.ReadFull(t, headerdata[4:]); err != nil {
- return nil, err
- }
- dec := newDecoder(bytes.NewBuffer(headerdata), order)
- dec.pos = 12
- vs, err := dec.Decode(Signature{"a(yv)"})
- if err != nil {
- return nil, err
- }
- Store(vs, &headers)
- for _, v := range headers {
- if v.Field == byte(FieldUnixFDs) {
- unixfds, _ = v.Variant.value.(uint32)
- }
- }
- all := make([]byte, 16+hlen+blen)
- copy(all, csheader[:])
- copy(all[16:], headerdata[4:])
- if _, err := io.ReadFull(rd, all[16+hlen:]); err != nil {
- return nil, err
- }
- if unixfds != 0 {
- if !t.hasUnixFDs {
- return nil, errors.New("dbus: got unix fds on unsupported transport")
- }
- // read the fds from the OOB data
- scms, err := syscall.ParseSocketControlMessage(rd.oob)
- if err != nil {
- return nil, err
- }
- if len(scms) != 1 {
- return nil, errors.New("dbus: received more than one socket control message")
- }
- fds, err := syscall.ParseUnixRights(&scms[0])
- if err != nil {
- return nil, err
- }
- msg, err := DecodeMessage(bytes.NewBuffer(all))
- if err != nil {
- return nil, err
- }
- // substitute the values in the message body (which are indices for the
- // array receiver via OOB) with the actual values
- for i, v := range msg.Body {
- if j, ok := v.(UnixFDIndex); ok {
- if uint32(j) >= unixfds {
- return nil, InvalidMessageError("invalid index for unix fd")
- }
- msg.Body[i] = UnixFD(fds[j])
- }
- }
- return msg, nil
- }
- return DecodeMessage(bytes.NewBuffer(all))
-}
-
-func (t *unixTransport) SendMessage(msg *Message) error {
- fds := make([]int, 0)
- for i, v := range msg.Body {
- if fd, ok := v.(UnixFD); ok {
- msg.Body[i] = UnixFDIndex(len(fds))
- fds = append(fds, int(fd))
- }
- }
- if len(fds) != 0 {
- if !t.hasUnixFDs {
- return errors.New("dbus: unix fd passing not enabled")
- }
- msg.Headers[FieldUnixFDs] = MakeVariant(uint32(len(fds)))
- oob := syscall.UnixRights(fds...)
- buf := new(bytes.Buffer)
- msg.EncodeTo(buf, binary.LittleEndian)
- n, oobn, err := t.UnixConn.WriteMsgUnix(buf.Bytes(), oob, nil)
- if err != nil {
- return err
- }
- if n != buf.Len() || oobn != len(oob) {
- return io.ErrShortWrite
- }
- } else {
- if err := msg.EncodeTo(t, binary.LittleEndian); err != nil {
- return nil
- }
- }
- return nil
-}
-
-func (t *unixTransport) SupportsUnixFDs() bool {
- return true
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/transport_unixcred_dragonfly.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/transport_unixcred_dragonfly.go
deleted file mode 100644
index a8cd3939..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/transport_unixcred_dragonfly.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// The UnixCredentials system call is currently only implemented on Linux
-// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
-// https://golang.org/s/go1.4-syscall
-// http://code.google.com/p/go/source/browse/unix/sockcmsg_linux.go?repo=sys
-
-// Local implementation of the UnixCredentials system call for DragonFly BSD
-
-package dbus
-
-/*
-#include
-*/
-import "C"
-
-import (
- "io"
- "os"
- "syscall"
- "unsafe"
-)
-
-// http://golang.org/src/pkg/syscall/ztypes_linux_amd64.go
-// http://golang.org/src/pkg/syscall/ztypes_dragonfly_amd64.go
-type Ucred struct {
- Pid int32
- Uid uint32
- Gid uint32
-}
-
-// http://golang.org/src/pkg/syscall/types_linux.go
-// http://golang.org/src/pkg/syscall/types_dragonfly.go
-// https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sys/sys/ucred.h
-const (
- SizeofUcred = C.sizeof_struct_ucred
-)
-
-// http://golang.org/src/pkg/syscall/sockcmsg_unix.go
-func cmsgAlignOf(salen int) int {
- // From http://golang.org/src/pkg/syscall/sockcmsg_unix.go
- //salign := sizeofPtr
- // NOTE: It seems like 64-bit Darwin and DragonFly BSD kernels
- // still require 32-bit aligned access to network subsystem.
- //if darwin64Bit || dragonfly64Bit {
- // salign = 4
- //}
- salign := 4
- return (salen + salign - 1) & ^(salign - 1)
-}
-
-// http://golang.org/src/pkg/syscall/sockcmsg_unix.go
-func cmsgData(h *syscall.Cmsghdr) unsafe.Pointer {
- return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(syscall.SizeofCmsghdr)))
-}
-
-// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
-// UnixCredentials encodes credentials into a socket control message
-// for sending to another process. This can be used for
-// authentication.
-func UnixCredentials(ucred *Ucred) []byte {
- b := make([]byte, syscall.CmsgSpace(SizeofUcred))
- h := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
- h.Level = syscall.SOL_SOCKET
- h.Type = syscall.SCM_CREDS
- h.SetLen(syscall.CmsgLen(SizeofUcred))
- *((*Ucred)(cmsgData(h))) = *ucred
- return b
-}
-
-// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
-// ParseUnixCredentials decodes a socket control message that contains
-// credentials in a Ucred structure. To receive such a message, the
-// SO_PASSCRED option must be enabled on the socket.
-func ParseUnixCredentials(m *syscall.SocketControlMessage) (*Ucred, error) {
- if m.Header.Level != syscall.SOL_SOCKET {
- return nil, syscall.EINVAL
- }
- if m.Header.Type != syscall.SCM_CREDS {
- return nil, syscall.EINVAL
- }
- ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
- return &ucred, nil
-}
-
-func (t *unixTransport) SendNullByte() error {
- ucred := &Ucred{Pid: int32(os.Getpid()), Uid: uint32(os.Getuid()), Gid: uint32(os.Getgid())}
- b := UnixCredentials(ucred)
- _, oobn, err := t.UnixConn.WriteMsgUnix([]byte{0}, b, nil)
- if err != nil {
- return err
- }
- if oobn != len(b) {
- return io.ErrShortWrite
- }
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/transport_unixcred_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/transport_unixcred_linux.go
deleted file mode 100644
index d9dfdf69..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/transport_unixcred_linux.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// The UnixCredentials system call is currently only implemented on Linux
-// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
-// https://golang.org/s/go1.4-syscall
-// http://code.google.com/p/go/source/browse/unix/sockcmsg_linux.go?repo=sys
-
-package dbus
-
-import (
- "io"
- "os"
- "syscall"
-)
-
-func (t *unixTransport) SendNullByte() error {
- ucred := &syscall.Ucred{Pid: int32(os.Getpid()), Uid: uint32(os.Getuid()), Gid: uint32(os.Getgid())}
- b := syscall.UnixCredentials(ucred)
- _, oobn, err := t.UnixConn.WriteMsgUnix([]byte{0}, b, nil)
- if err != nil {
- return err
- }
- if oobn != len(b) {
- return io.ErrShortWrite
- }
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/variant.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/variant.go
deleted file mode 100644
index b7b13ae9..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/variant.go
+++ /dev/null
@@ -1,139 +0,0 @@
-package dbus
-
-import (
- "bytes"
- "fmt"
- "reflect"
- "sort"
- "strconv"
-)
-
-// Variant represents the D-Bus variant type.
-type Variant struct {
- sig Signature
- value interface{}
-}
-
-// MakeVariant converts the given value to a Variant. It panics if v cannot be
-// represented as a D-Bus type.
-func MakeVariant(v interface{}) Variant {
- return Variant{SignatureOf(v), v}
-}
-
-// ParseVariant parses the given string as a variant as described at
-// https://developer.gnome.org/glib/unstable/gvariant-text.html. If sig is not
-// empty, it is taken to be the expected signature for the variant.
-func ParseVariant(s string, sig Signature) (Variant, error) {
- tokens := varLex(s)
- p := &varParser{tokens: tokens}
- n, err := varMakeNode(p)
- if err != nil {
- return Variant{}, err
- }
- if sig.str == "" {
- sig, err = varInfer(n)
- if err != nil {
- return Variant{}, err
- }
- }
- v, err := n.Value(sig)
- if err != nil {
- return Variant{}, err
- }
- return MakeVariant(v), nil
-}
-
-// format returns a formatted version of v and whether this string can be parsed
-// unambigously.
-func (v Variant) format() (string, bool) {
- switch v.sig.str[0] {
- case 'b', 'i':
- return fmt.Sprint(v.value), true
- case 'n', 'q', 'u', 'x', 't', 'd', 'h':
- return fmt.Sprint(v.value), false
- case 's':
- return strconv.Quote(v.value.(string)), true
- case 'o':
- return strconv.Quote(string(v.value.(ObjectPath))), false
- case 'g':
- return strconv.Quote(v.value.(Signature).str), false
- case 'v':
- s, unamb := v.value.(Variant).format()
- if !unamb {
- return "<@" + v.value.(Variant).sig.str + " " + s + ">", true
- }
- return "<" + s + ">", true
- case 'y':
- return fmt.Sprintf("%#x", v.value.(byte)), false
- }
- rv := reflect.ValueOf(v.value)
- switch rv.Kind() {
- case reflect.Slice:
- if rv.Len() == 0 {
- return "[]", false
- }
- unamb := true
- buf := bytes.NewBuffer([]byte("["))
- for i := 0; i < rv.Len(); i++ {
- // TODO: slooow
- s, b := MakeVariant(rv.Index(i).Interface()).format()
- unamb = unamb && b
- buf.WriteString(s)
- if i != rv.Len()-1 {
- buf.WriteString(", ")
- }
- }
- buf.WriteByte(']')
- return buf.String(), unamb
- case reflect.Map:
- if rv.Len() == 0 {
- return "{}", false
- }
- unamb := true
- var buf bytes.Buffer
- kvs := make([]string, rv.Len())
- for i, k := range rv.MapKeys() {
- s, b := MakeVariant(k.Interface()).format()
- unamb = unamb && b
- buf.Reset()
- buf.WriteString(s)
- buf.WriteString(": ")
- s, b = MakeVariant(rv.MapIndex(k).Interface()).format()
- unamb = unamb && b
- buf.WriteString(s)
- kvs[i] = buf.String()
- }
- buf.Reset()
- buf.WriteByte('{')
- sort.Strings(kvs)
- for i, kv := range kvs {
- if i > 0 {
- buf.WriteString(", ")
- }
- buf.WriteString(kv)
- }
- buf.WriteByte('}')
- return buf.String(), unamb
- }
- return `"INVALID"`, true
-}
-
-// Signature returns the D-Bus signature of the underlying value of v.
-func (v Variant) Signature() Signature {
- return v.sig
-}
-
-// String returns the string representation of the underlying value of v as
-// described at https://developer.gnome.org/glib/unstable/gvariant-text.html.
-func (v Variant) String() string {
- s, unamb := v.format()
- if !unamb {
- return "@" + v.sig.str + " " + s
- }
- return s
-}
-
-// Value returns the underlying value of v.
-func (v Variant) Value() interface{} {
- return v.value
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/variant_lexer.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/variant_lexer.go
deleted file mode 100644
index 332007d6..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/variant_lexer.go
+++ /dev/null
@@ -1,284 +0,0 @@
-package dbus
-
-import (
- "fmt"
- "strings"
- "unicode"
- "unicode/utf8"
-)
-
-// Heavily inspired by the lexer from text/template.
-
-type varToken struct {
- typ varTokenType
- val string
-}
-
-type varTokenType byte
-
-const (
- tokEOF varTokenType = iota
- tokError
- tokNumber
- tokString
- tokBool
- tokArrayStart
- tokArrayEnd
- tokDictStart
- tokDictEnd
- tokVariantStart
- tokVariantEnd
- tokComma
- tokColon
- tokType
- tokByteString
-)
-
-type varLexer struct {
- input string
- start int
- pos int
- width int
- tokens []varToken
-}
-
-type lexState func(*varLexer) lexState
-
-func varLex(s string) []varToken {
- l := &varLexer{input: s}
- l.run()
- return l.tokens
-}
-
-func (l *varLexer) accept(valid string) bool {
- if strings.IndexRune(valid, l.next()) >= 0 {
- return true
- }
- l.backup()
- return false
-}
-
-func (l *varLexer) backup() {
- l.pos -= l.width
-}
-
-func (l *varLexer) emit(t varTokenType) {
- l.tokens = append(l.tokens, varToken{t, l.input[l.start:l.pos]})
- l.start = l.pos
-}
-
-func (l *varLexer) errorf(format string, v ...interface{}) lexState {
- l.tokens = append(l.tokens, varToken{
- tokError,
- fmt.Sprintf(format, v...),
- })
- return nil
-}
-
-func (l *varLexer) ignore() {
- l.start = l.pos
-}
-
-func (l *varLexer) next() rune {
- var r rune
-
- if l.pos >= len(l.input) {
- l.width = 0
- return -1
- }
- r, l.width = utf8.DecodeRuneInString(l.input[l.pos:])
- l.pos += l.width
- return r
-}
-
-func (l *varLexer) run() {
- for state := varLexNormal; state != nil; {
- state = state(l)
- }
-}
-
-func (l *varLexer) peek() rune {
- r := l.next()
- l.backup()
- return r
-}
-
-func varLexNormal(l *varLexer) lexState {
- for {
- r := l.next()
- switch {
- case r == -1:
- l.emit(tokEOF)
- return nil
- case r == '[':
- l.emit(tokArrayStart)
- case r == ']':
- l.emit(tokArrayEnd)
- case r == '{':
- l.emit(tokDictStart)
- case r == '}':
- l.emit(tokDictEnd)
- case r == '<':
- l.emit(tokVariantStart)
- case r == '>':
- l.emit(tokVariantEnd)
- case r == ':':
- l.emit(tokColon)
- case r == ',':
- l.emit(tokComma)
- case r == '\'' || r == '"':
- l.backup()
- return varLexString
- case r == '@':
- l.backup()
- return varLexType
- case unicode.IsSpace(r):
- l.ignore()
- case unicode.IsNumber(r) || r == '+' || r == '-':
- l.backup()
- return varLexNumber
- case r == 'b':
- pos := l.start
- if n := l.peek(); n == '"' || n == '\'' {
- return varLexByteString
- }
- // not a byte string; try to parse it as a type or bool below
- l.pos = pos + 1
- l.width = 1
- fallthrough
- default:
- // either a bool or a type. Try bools first.
- l.backup()
- if l.pos+4 <= len(l.input) {
- if l.input[l.pos:l.pos+4] == "true" {
- l.pos += 4
- l.emit(tokBool)
- continue
- }
- }
- if l.pos+5 <= len(l.input) {
- if l.input[l.pos:l.pos+5] == "false" {
- l.pos += 5
- l.emit(tokBool)
- continue
- }
- }
- // must be a type.
- return varLexType
- }
- }
-}
-
-var varTypeMap = map[string]string{
- "boolean": "b",
- "byte": "y",
- "int16": "n",
- "uint16": "q",
- "int32": "i",
- "uint32": "u",
- "int64": "x",
- "uint64": "t",
- "double": "f",
- "string": "s",
- "objectpath": "o",
- "signature": "g",
-}
-
-func varLexByteString(l *varLexer) lexState {
- q := l.next()
-Loop:
- for {
- switch l.next() {
- case '\\':
- if r := l.next(); r != -1 {
- break
- }
- fallthrough
- case -1:
- return l.errorf("unterminated bytestring")
- case q:
- break Loop
- }
- }
- l.emit(tokByteString)
- return varLexNormal
-}
-
-func varLexNumber(l *varLexer) lexState {
- l.accept("+-")
- digits := "0123456789"
- if l.accept("0") {
- if l.accept("x") {
- digits = "0123456789abcdefABCDEF"
- } else {
- digits = "01234567"
- }
- }
- for strings.IndexRune(digits, l.next()) >= 0 {
- }
- l.backup()
- if l.accept(".") {
- for strings.IndexRune(digits, l.next()) >= 0 {
- }
- l.backup()
- }
- if l.accept("eE") {
- l.accept("+-")
- for strings.IndexRune("0123456789", l.next()) >= 0 {
- }
- l.backup()
- }
- if r := l.peek(); unicode.IsLetter(r) {
- l.next()
- return l.errorf("bad number syntax: %q", l.input[l.start:l.pos])
- }
- l.emit(tokNumber)
- return varLexNormal
-}
-
-func varLexString(l *varLexer) lexState {
- q := l.next()
-Loop:
- for {
- switch l.next() {
- case '\\':
- if r := l.next(); r != -1 {
- break
- }
- fallthrough
- case -1:
- return l.errorf("unterminated string")
- case q:
- break Loop
- }
- }
- l.emit(tokString)
- return varLexNormal
-}
-
-func varLexType(l *varLexer) lexState {
- at := l.accept("@")
- for {
- r := l.next()
- if r == -1 {
- break
- }
- if unicode.IsSpace(r) {
- l.backup()
- break
- }
- }
- if at {
- if _, err := ParseSignature(l.input[l.start+1 : l.pos]); err != nil {
- return l.errorf("%s", err)
- }
- } else {
- if _, ok := varTypeMap[l.input[l.start:l.pos]]; ok {
- l.emit(tokType)
- return varLexNormal
- }
- return l.errorf("unrecognized type %q", l.input[l.start:l.pos])
- }
- l.emit(tokType)
- return varLexNormal
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/variant_parser.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/variant_parser.go
deleted file mode 100644
index d20f5da6..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/godbus/dbus/variant_parser.go
+++ /dev/null
@@ -1,817 +0,0 @@
-package dbus
-
-import (
- "bytes"
- "errors"
- "fmt"
- "io"
- "reflect"
- "strconv"
- "strings"
- "unicode/utf8"
-)
-
-type varParser struct {
- tokens []varToken
- i int
-}
-
-func (p *varParser) backup() {
- p.i--
-}
-
-func (p *varParser) next() varToken {
- if p.i < len(p.tokens) {
- t := p.tokens[p.i]
- p.i++
- return t
- }
- return varToken{typ: tokEOF}
-}
-
-type varNode interface {
- Infer() (Signature, error)
- String() string
- Sigs() sigSet
- Value(Signature) (interface{}, error)
-}
-
-func varMakeNode(p *varParser) (varNode, error) {
- var sig Signature
-
- for {
- t := p.next()
- switch t.typ {
- case tokEOF:
- return nil, io.ErrUnexpectedEOF
- case tokError:
- return nil, errors.New(t.val)
- case tokNumber:
- return varMakeNumNode(t, sig)
- case tokString:
- return varMakeStringNode(t, sig)
- case tokBool:
- if sig.str != "" && sig.str != "b" {
- return nil, varTypeError{t.val, sig}
- }
- b, err := strconv.ParseBool(t.val)
- if err != nil {
- return nil, err
- }
- return boolNode(b), nil
- case tokArrayStart:
- return varMakeArrayNode(p, sig)
- case tokVariantStart:
- return varMakeVariantNode(p, sig)
- case tokDictStart:
- return varMakeDictNode(p, sig)
- case tokType:
- if sig.str != "" {
- return nil, errors.New("unexpected type annotation")
- }
- if t.val[0] == '@' {
- sig.str = t.val[1:]
- } else {
- sig.str = varTypeMap[t.val]
- }
- case tokByteString:
- if sig.str != "" && sig.str != "ay" {
- return nil, varTypeError{t.val, sig}
- }
- b, err := varParseByteString(t.val)
- if err != nil {
- return nil, err
- }
- return byteStringNode(b), nil
- default:
- return nil, fmt.Errorf("unexpected %q", t.val)
- }
- }
-}
-
-type varTypeError struct {
- val string
- sig Signature
-}
-
-func (e varTypeError) Error() string {
- return fmt.Sprintf("dbus: can't parse %q as type %q", e.val, e.sig.str)
-}
-
-type sigSet map[Signature]bool
-
-func (s sigSet) Empty() bool {
- return len(s) == 0
-}
-
-func (s sigSet) Intersect(s2 sigSet) sigSet {
- r := make(sigSet)
- for k := range s {
- if s2[k] {
- r[k] = true
- }
- }
- return r
-}
-
-func (s sigSet) Single() (Signature, bool) {
- if len(s) == 1 {
- for k := range s {
- return k, true
- }
- }
- return Signature{}, false
-}
-
-func (s sigSet) ToArray() sigSet {
- r := make(sigSet, len(s))
- for k := range s {
- r[Signature{"a" + k.str}] = true
- }
- return r
-}
-
-type numNode struct {
- sig Signature
- str string
- val interface{}
-}
-
-var numSigSet = sigSet{
- Signature{"y"}: true,
- Signature{"n"}: true,
- Signature{"q"}: true,
- Signature{"i"}: true,
- Signature{"u"}: true,
- Signature{"x"}: true,
- Signature{"t"}: true,
- Signature{"d"}: true,
-}
-
-func (n numNode) Infer() (Signature, error) {
- if strings.ContainsAny(n.str, ".e") {
- return Signature{"d"}, nil
- }
- return Signature{"i"}, nil
-}
-
-func (n numNode) String() string {
- return n.str
-}
-
-func (n numNode) Sigs() sigSet {
- if n.sig.str != "" {
- return sigSet{n.sig: true}
- }
- if strings.ContainsAny(n.str, ".e") {
- return sigSet{Signature{"d"}: true}
- }
- return numSigSet
-}
-
-func (n numNode) Value(sig Signature) (interface{}, error) {
- if n.sig.str != "" && n.sig != sig {
- return nil, varTypeError{n.str, sig}
- }
- if n.val != nil {
- return n.val, nil
- }
- return varNumAs(n.str, sig)
-}
-
-func varMakeNumNode(tok varToken, sig Signature) (varNode, error) {
- if sig.str == "" {
- return numNode{str: tok.val}, nil
- }
- num, err := varNumAs(tok.val, sig)
- if err != nil {
- return nil, err
- }
- return numNode{sig: sig, val: num}, nil
-}
-
-func varNumAs(s string, sig Signature) (interface{}, error) {
- isUnsigned := false
- size := 32
- switch sig.str {
- case "n":
- size = 16
- case "i":
- case "x":
- size = 64
- case "y":
- size = 8
- isUnsigned = true
- case "q":
- size = 16
- isUnsigned = true
- case "u":
- isUnsigned = true
- case "t":
- size = 64
- isUnsigned = true
- case "d":
- d, err := strconv.ParseFloat(s, 64)
- if err != nil {
- return nil, err
- }
- return d, nil
- default:
- return nil, varTypeError{s, sig}
- }
- base := 10
- if strings.HasPrefix(s, "0x") {
- base = 16
- s = s[2:]
- }
- if strings.HasPrefix(s, "0") && len(s) != 1 {
- base = 8
- s = s[1:]
- }
- if isUnsigned {
- i, err := strconv.ParseUint(s, base, size)
- if err != nil {
- return nil, err
- }
- var v interface{} = i
- switch sig.str {
- case "y":
- v = byte(i)
- case "q":
- v = uint16(i)
- case "u":
- v = uint32(i)
- }
- return v, nil
- }
- i, err := strconv.ParseInt(s, base, size)
- if err != nil {
- return nil, err
- }
- var v interface{} = i
- switch sig.str {
- case "n":
- v = int16(i)
- case "i":
- v = int32(i)
- }
- return v, nil
-}
-
-type stringNode struct {
- sig Signature
- str string // parsed
- val interface{} // has correct type
-}
-
-var stringSigSet = sigSet{
- Signature{"s"}: true,
- Signature{"g"}: true,
- Signature{"o"}: true,
-}
-
-func (n stringNode) Infer() (Signature, error) {
- return Signature{"s"}, nil
-}
-
-func (n stringNode) String() string {
- return n.str
-}
-
-func (n stringNode) Sigs() sigSet {
- if n.sig.str != "" {
- return sigSet{n.sig: true}
- }
- return stringSigSet
-}
-
-func (n stringNode) Value(sig Signature) (interface{}, error) {
- if n.sig.str != "" && n.sig != sig {
- return nil, varTypeError{n.str, sig}
- }
- if n.val != nil {
- return n.val, nil
- }
- switch {
- case sig.str == "g":
- return Signature{n.str}, nil
- case sig.str == "o":
- return ObjectPath(n.str), nil
- case sig.str == "s":
- return n.str, nil
- default:
- return nil, varTypeError{n.str, sig}
- }
-}
-
-func varMakeStringNode(tok varToken, sig Signature) (varNode, error) {
- if sig.str != "" && sig.str != "s" && sig.str != "g" && sig.str != "o" {
- return nil, fmt.Errorf("invalid type %q for string", sig.str)
- }
- s, err := varParseString(tok.val)
- if err != nil {
- return nil, err
- }
- n := stringNode{str: s}
- if sig.str == "" {
- return stringNode{str: s}, nil
- }
- n.sig = sig
- switch sig.str {
- case "o":
- n.val = ObjectPath(s)
- case "g":
- n.val = Signature{s}
- case "s":
- n.val = s
- }
- return n, nil
-}
-
-func varParseString(s string) (string, error) {
- // quotes are guaranteed to be there
- s = s[1 : len(s)-1]
- buf := new(bytes.Buffer)
- for len(s) != 0 {
- r, size := utf8.DecodeRuneInString(s)
- if r == utf8.RuneError && size == 1 {
- return "", errors.New("invalid UTF-8")
- }
- s = s[size:]
- if r != '\\' {
- buf.WriteRune(r)
- continue
- }
- r, size = utf8.DecodeRuneInString(s)
- if r == utf8.RuneError && size == 1 {
- return "", errors.New("invalid UTF-8")
- }
- s = s[size:]
- switch r {
- case 'a':
- buf.WriteRune(0x7)
- case 'b':
- buf.WriteRune(0x8)
- case 'f':
- buf.WriteRune(0xc)
- case 'n':
- buf.WriteRune('\n')
- case 'r':
- buf.WriteRune('\r')
- case 't':
- buf.WriteRune('\t')
- case '\n':
- case 'u':
- if len(s) < 4 {
- return "", errors.New("short unicode escape")
- }
- r, err := strconv.ParseUint(s[:4], 16, 32)
- if err != nil {
- return "", err
- }
- buf.WriteRune(rune(r))
- s = s[4:]
- case 'U':
- if len(s) < 8 {
- return "", errors.New("short unicode escape")
- }
- r, err := strconv.ParseUint(s[:8], 16, 32)
- if err != nil {
- return "", err
- }
- buf.WriteRune(rune(r))
- s = s[8:]
- default:
- buf.WriteRune(r)
- }
- }
- return buf.String(), nil
-}
-
-var boolSigSet = sigSet{Signature{"b"}: true}
-
-type boolNode bool
-
-func (boolNode) Infer() (Signature, error) {
- return Signature{"b"}, nil
-}
-
-func (b boolNode) String() string {
- if b {
- return "true"
- }
- return "false"
-}
-
-func (boolNode) Sigs() sigSet {
- return boolSigSet
-}
-
-func (b boolNode) Value(sig Signature) (interface{}, error) {
- if sig.str != "b" {
- return nil, varTypeError{b.String(), sig}
- }
- return bool(b), nil
-}
-
-type arrayNode struct {
- set sigSet
- children []varNode
- val interface{}
-}
-
-func (n arrayNode) Infer() (Signature, error) {
- for _, v := range n.children {
- csig, err := varInfer(v)
- if err != nil {
- continue
- }
- return Signature{"a" + csig.str}, nil
- }
- return Signature{}, fmt.Errorf("can't infer type for %q", n.String())
-}
-
-func (n arrayNode) String() string {
- s := "["
- for i, v := range n.children {
- s += v.String()
- if i != len(n.children)-1 {
- s += ", "
- }
- }
- return s + "]"
-}
-
-func (n arrayNode) Sigs() sigSet {
- return n.set
-}
-
-func (n arrayNode) Value(sig Signature) (interface{}, error) {
- if n.set.Empty() {
- // no type information whatsoever, so this must be an empty slice
- return reflect.MakeSlice(typeFor(sig.str), 0, 0).Interface(), nil
- }
- if !n.set[sig] {
- return nil, varTypeError{n.String(), sig}
- }
- s := reflect.MakeSlice(typeFor(sig.str), len(n.children), len(n.children))
- for i, v := range n.children {
- rv, err := v.Value(Signature{sig.str[1:]})
- if err != nil {
- return nil, err
- }
- s.Index(i).Set(reflect.ValueOf(rv))
- }
- return s.Interface(), nil
-}
-
-func varMakeArrayNode(p *varParser, sig Signature) (varNode, error) {
- var n arrayNode
- if sig.str != "" {
- n.set = sigSet{sig: true}
- }
- if t := p.next(); t.typ == tokArrayEnd {
- return n, nil
- } else {
- p.backup()
- }
-Loop:
- for {
- t := p.next()
- switch t.typ {
- case tokEOF:
- return nil, io.ErrUnexpectedEOF
- case tokError:
- return nil, errors.New(t.val)
- }
- p.backup()
- cn, err := varMakeNode(p)
- if err != nil {
- return nil, err
- }
- if cset := cn.Sigs(); !cset.Empty() {
- if n.set.Empty() {
- n.set = cset.ToArray()
- } else {
- nset := cset.ToArray().Intersect(n.set)
- if nset.Empty() {
- return nil, fmt.Errorf("can't parse %q with given type information", cn.String())
- }
- n.set = nset
- }
- }
- n.children = append(n.children, cn)
- switch t := p.next(); t.typ {
- case tokEOF:
- return nil, io.ErrUnexpectedEOF
- case tokError:
- return nil, errors.New(t.val)
- case tokArrayEnd:
- break Loop
- case tokComma:
- continue
- default:
- return nil, fmt.Errorf("unexpected %q", t.val)
- }
- }
- return n, nil
-}
-
-type variantNode struct {
- n varNode
-}
-
-var variantSet = sigSet{
- Signature{"v"}: true,
-}
-
-func (variantNode) Infer() (Signature, error) {
- return Signature{"v"}, nil
-}
-
-func (n variantNode) String() string {
- return "<" + n.n.String() + ">"
-}
-
-func (variantNode) Sigs() sigSet {
- return variantSet
-}
-
-func (n variantNode) Value(sig Signature) (interface{}, error) {
- if sig.str != "v" {
- return nil, varTypeError{n.String(), sig}
- }
- sig, err := varInfer(n.n)
- if err != nil {
- return nil, err
- }
- v, err := n.n.Value(sig)
- if err != nil {
- return nil, err
- }
- return MakeVariant(v), nil
-}
-
-func varMakeVariantNode(p *varParser, sig Signature) (varNode, error) {
- n, err := varMakeNode(p)
- if err != nil {
- return nil, err
- }
- if t := p.next(); t.typ != tokVariantEnd {
- return nil, fmt.Errorf("unexpected %q", t.val)
- }
- vn := variantNode{n}
- if sig.str != "" && sig.str != "v" {
- return nil, varTypeError{vn.String(), sig}
- }
- return variantNode{n}, nil
-}
-
-type dictEntry struct {
- key, val varNode
-}
-
-type dictNode struct {
- kset, vset sigSet
- children []dictEntry
- val interface{}
-}
-
-func (n dictNode) Infer() (Signature, error) {
- for _, v := range n.children {
- ksig, err := varInfer(v.key)
- if err != nil {
- continue
- }
- vsig, err := varInfer(v.val)
- if err != nil {
- continue
- }
- return Signature{"a{" + ksig.str + vsig.str + "}"}, nil
- }
- return Signature{}, fmt.Errorf("can't infer type for %q", n.String())
-}
-
-func (n dictNode) String() string {
- s := "{"
- for i, v := range n.children {
- s += v.key.String() + ": " + v.val.String()
- if i != len(n.children)-1 {
- s += ", "
- }
- }
- return s + "}"
-}
-
-func (n dictNode) Sigs() sigSet {
- r := sigSet{}
- for k := range n.kset {
- for v := range n.vset {
- sig := "a{" + k.str + v.str + "}"
- r[Signature{sig}] = true
- }
- }
- return r
-}
-
-func (n dictNode) Value(sig Signature) (interface{}, error) {
- set := n.Sigs()
- if set.Empty() {
- // no type information -> empty dict
- return reflect.MakeMap(typeFor(sig.str)).Interface(), nil
- }
- if !set[sig] {
- return nil, varTypeError{n.String(), sig}
- }
- m := reflect.MakeMap(typeFor(sig.str))
- ksig := Signature{sig.str[2:3]}
- vsig := Signature{sig.str[3 : len(sig.str)-1]}
- for _, v := range n.children {
- kv, err := v.key.Value(ksig)
- if err != nil {
- return nil, err
- }
- vv, err := v.val.Value(vsig)
- if err != nil {
- return nil, err
- }
- m.SetMapIndex(reflect.ValueOf(kv), reflect.ValueOf(vv))
- }
- return m.Interface(), nil
-}
-
-func varMakeDictNode(p *varParser, sig Signature) (varNode, error) {
- var n dictNode
-
- if sig.str != "" {
- if len(sig.str) < 5 {
- return nil, fmt.Errorf("invalid signature %q for dict type", sig)
- }
- ksig := Signature{string(sig.str[2])}
- vsig := Signature{sig.str[3 : len(sig.str)-1]}
- n.kset = sigSet{ksig: true}
- n.vset = sigSet{vsig: true}
- }
- if t := p.next(); t.typ == tokDictEnd {
- return n, nil
- } else {
- p.backup()
- }
-Loop:
- for {
- t := p.next()
- switch t.typ {
- case tokEOF:
- return nil, io.ErrUnexpectedEOF
- case tokError:
- return nil, errors.New(t.val)
- }
- p.backup()
- kn, err := varMakeNode(p)
- if err != nil {
- return nil, err
- }
- if kset := kn.Sigs(); !kset.Empty() {
- if n.kset.Empty() {
- n.kset = kset
- } else {
- n.kset = kset.Intersect(n.kset)
- if n.kset.Empty() {
- return nil, fmt.Errorf("can't parse %q with given type information", kn.String())
- }
- }
- }
- t = p.next()
- switch t.typ {
- case tokEOF:
- return nil, io.ErrUnexpectedEOF
- case tokError:
- return nil, errors.New(t.val)
- case tokColon:
- default:
- return nil, fmt.Errorf("unexpected %q", t.val)
- }
- t = p.next()
- switch t.typ {
- case tokEOF:
- return nil, io.ErrUnexpectedEOF
- case tokError:
- return nil, errors.New(t.val)
- }
- p.backup()
- vn, err := varMakeNode(p)
- if err != nil {
- return nil, err
- }
- if vset := vn.Sigs(); !vset.Empty() {
- if n.vset.Empty() {
- n.vset = vset
- } else {
- n.vset = n.vset.Intersect(vset)
- if n.vset.Empty() {
- return nil, fmt.Errorf("can't parse %q with given type information", vn.String())
- }
- }
- }
- n.children = append(n.children, dictEntry{kn, vn})
- t = p.next()
- switch t.typ {
- case tokEOF:
- return nil, io.ErrUnexpectedEOF
- case tokError:
- return nil, errors.New(t.val)
- case tokDictEnd:
- break Loop
- case tokComma:
- continue
- default:
- return nil, fmt.Errorf("unexpected %q", t.val)
- }
- }
- return n, nil
-}
-
-type byteStringNode []byte
-
-var byteStringSet = sigSet{
- Signature{"ay"}: true,
-}
-
-func (byteStringNode) Infer() (Signature, error) {
- return Signature{"ay"}, nil
-}
-
-func (b byteStringNode) String() string {
- return string(b)
-}
-
-func (b byteStringNode) Sigs() sigSet {
- return byteStringSet
-}
-
-func (b byteStringNode) Value(sig Signature) (interface{}, error) {
- if sig.str != "ay" {
- return nil, varTypeError{b.String(), sig}
- }
- return []byte(b), nil
-}
-
-func varParseByteString(s string) ([]byte, error) {
- // quotes and b at start are guaranteed to be there
- b := make([]byte, 0, 1)
- s = s[2 : len(s)-1]
- for len(s) != 0 {
- c := s[0]
- s = s[1:]
- if c != '\\' {
- b = append(b, c)
- continue
- }
- c = s[0]
- s = s[1:]
- switch c {
- case 'a':
- b = append(b, 0x7)
- case 'b':
- b = append(b, 0x8)
- case 'f':
- b = append(b, 0xc)
- case 'n':
- b = append(b, '\n')
- case 'r':
- b = append(b, '\r')
- case 't':
- b = append(b, '\t')
- case 'x':
- if len(s) < 2 {
- return nil, errors.New("short escape")
- }
- n, err := strconv.ParseUint(s[:2], 16, 8)
- if err != nil {
- return nil, err
- }
- b = append(b, byte(n))
- s = s[2:]
- case '0':
- if len(s) < 3 {
- return nil, errors.New("short escape")
- }
- n, err := strconv.ParseUint(s[:3], 8, 8)
- if err != nil {
- return nil, err
- }
- b = append(b, byte(n))
- s = s[3:]
- default:
- b = append(b, c)
- }
- }
- return append(b, 0), nil
-}
-
-func varInfer(n varNode) (Signature, error) {
- if sig, ok := n.Sigs().Single(); ok {
- return sig, nil
- }
- return n.Infer()
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/LICENSE b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/LICENSE
deleted file mode 100644
index 1b1b1921..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/LICENSE
+++ /dev/null
@@ -1,31 +0,0 @@
-Go support for Protocol Buffers - Google's data interchange format
-
-Copyright 2010 The Go Authors. All rights reserved.
-https://github.com/golang/protobuf
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/Makefile b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/Makefile
deleted file mode 100644
index fb838ed2..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/Makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-# Go support for Protocol Buffers - Google's data interchange format
-#
-# Copyright 2010 The Go Authors. All rights reserved.
-# https://github.com/golang/protobuf
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-install:
- go install
-
-test: install generate-test-pbs
- go test
-
-
-generate-test-pbs:
- make install
- make -C testdata
- make -C proto3_proto
- make
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/clone.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/clone.go
deleted file mode 100644
index 6c6a7d95..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/clone.go
+++ /dev/null
@@ -1,197 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2011 The Go Authors. All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Protocol buffer deep copy and merge.
-// TODO: MessageSet and RawMessage.
-
-package proto
-
-import (
- "log"
- "reflect"
- "strings"
-)
-
-// Clone returns a deep copy of a protocol buffer.
-func Clone(pb Message) Message {
- in := reflect.ValueOf(pb)
- if in.IsNil() {
- return pb
- }
-
- out := reflect.New(in.Type().Elem())
- // out is empty so a merge is a deep copy.
- mergeStruct(out.Elem(), in.Elem())
- return out.Interface().(Message)
-}
-
-// Merge merges src into dst.
-// Required and optional fields that are set in src will be set to that value in dst.
-// Elements of repeated fields will be appended.
-// Merge panics if src and dst are not the same type, or if dst is nil.
-func Merge(dst, src Message) {
- in := reflect.ValueOf(src)
- out := reflect.ValueOf(dst)
- if out.IsNil() {
- panic("proto: nil destination")
- }
- if in.Type() != out.Type() {
- // Explicit test prior to mergeStruct so that mistyped nils will fail
- panic("proto: type mismatch")
- }
- if in.IsNil() {
- // Merging nil into non-nil is a quiet no-op
- return
- }
- mergeStruct(out.Elem(), in.Elem())
-}
-
-func mergeStruct(out, in reflect.Value) {
- for i := 0; i < in.NumField(); i++ {
- f := in.Type().Field(i)
- if strings.HasPrefix(f.Name, "XXX_") {
- continue
- }
- mergeAny(out.Field(i), in.Field(i))
- }
-
- if emIn, ok := in.Addr().Interface().(extendableProto); ok {
- emOut := out.Addr().Interface().(extendableProto)
- mergeExtension(emOut.ExtensionMap(), emIn.ExtensionMap())
- }
-
- uf := in.FieldByName("XXX_unrecognized")
- if !uf.IsValid() {
- return
- }
- uin := uf.Bytes()
- if len(uin) > 0 {
- out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...))
- }
-}
-
-func mergeAny(out, in reflect.Value) {
- if in.Type() == protoMessageType {
- if !in.IsNil() {
- if out.IsNil() {
- out.Set(reflect.ValueOf(Clone(in.Interface().(Message))))
- } else {
- Merge(out.Interface().(Message), in.Interface().(Message))
- }
- }
- return
- }
- switch in.Kind() {
- case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
- reflect.String, reflect.Uint32, reflect.Uint64:
- out.Set(in)
- case reflect.Map:
- if in.Len() == 0 {
- return
- }
- if out.IsNil() {
- out.Set(reflect.MakeMap(in.Type()))
- }
- // For maps with value types of *T or []byte we need to deep copy each value.
- elemKind := in.Type().Elem().Kind()
- for _, key := range in.MapKeys() {
- var val reflect.Value
- switch elemKind {
- case reflect.Ptr:
- val = reflect.New(in.Type().Elem().Elem())
- mergeAny(val, in.MapIndex(key))
- case reflect.Slice:
- val = in.MapIndex(key)
- val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
- default:
- val = in.MapIndex(key)
- }
- out.SetMapIndex(key, val)
- }
- case reflect.Ptr:
- if in.IsNil() {
- return
- }
- if out.IsNil() {
- out.Set(reflect.New(in.Elem().Type()))
- }
- mergeAny(out.Elem(), in.Elem())
- case reflect.Slice:
- if in.IsNil() {
- return
- }
- if in.Type().Elem().Kind() == reflect.Uint8 {
- // []byte is a scalar bytes field, not a repeated field.
- // Make a deep copy.
- // Append to []byte{} instead of []byte(nil) so that we never end up
- // with a nil result.
- out.SetBytes(append([]byte{}, in.Bytes()...))
- return
- }
- n := in.Len()
- if out.IsNil() {
- out.Set(reflect.MakeSlice(in.Type(), 0, n))
- }
- switch in.Type().Elem().Kind() {
- case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
- reflect.String, reflect.Uint32, reflect.Uint64:
- out.Set(reflect.AppendSlice(out, in))
- default:
- for i := 0; i < n; i++ {
- x := reflect.Indirect(reflect.New(in.Type().Elem()))
- mergeAny(x, in.Index(i))
- out.Set(reflect.Append(out, x))
- }
- }
- case reflect.Struct:
- mergeStruct(out, in)
- default:
- // unknown type, so not a protocol buffer
- log.Printf("proto: don't know how to copy %v", in)
- }
-}
-
-func mergeExtension(out, in map[int32]Extension) {
- for extNum, eIn := range in {
- eOut := Extension{desc: eIn.desc}
- if eIn.value != nil {
- v := reflect.New(reflect.TypeOf(eIn.value)).Elem()
- mergeAny(v, reflect.ValueOf(eIn.value))
- eOut.value = v.Interface()
- }
- if eIn.enc != nil {
- eOut.enc = make([]byte, len(eIn.enc))
- copy(eOut.enc, eIn.enc)
- }
-
- out[extNum] = eOut
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/decode.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/decode.go
deleted file mode 100644
index 129792ed..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/decode.go
+++ /dev/null
@@ -1,821 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2010 The Go Authors. All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package proto
-
-/*
- * Routines for decoding protocol buffer data to construct in-memory representations.
- */
-
-import (
- "errors"
- "fmt"
- "io"
- "os"
- "reflect"
-)
-
-// errOverflow is returned when an integer is too large to be represented.
-var errOverflow = errors.New("proto: integer overflow")
-
-// The fundamental decoders that interpret bytes on the wire.
-// Those that take integer types all return uint64 and are
-// therefore of type valueDecoder.
-
-// DecodeVarint reads a varint-encoded integer from the slice.
-// It returns the integer and the number of bytes consumed, or
-// zero if there is not enough.
-// This is the format for the
-// int32, int64, uint32, uint64, bool, and enum
-// protocol buffer types.
-func DecodeVarint(buf []byte) (x uint64, n int) {
- // x, n already 0
- for shift := uint(0); shift < 64; shift += 7 {
- if n >= len(buf) {
- return 0, 0
- }
- b := uint64(buf[n])
- n++
- x |= (b & 0x7F) << shift
- if (b & 0x80) == 0 {
- return x, n
- }
- }
-
- // The number is too large to represent in a 64-bit value.
- return 0, 0
-}
-
-// DecodeVarint reads a varint-encoded integer from the Buffer.
-// This is the format for the
-// int32, int64, uint32, uint64, bool, and enum
-// protocol buffer types.
-func (p *Buffer) DecodeVarint() (x uint64, err error) {
- // x, err already 0
-
- i := p.index
- l := len(p.buf)
-
- for shift := uint(0); shift < 64; shift += 7 {
- if i >= l {
- err = io.ErrUnexpectedEOF
- return
- }
- b := p.buf[i]
- i++
- x |= (uint64(b) & 0x7F) << shift
- if b < 0x80 {
- p.index = i
- return
- }
- }
-
- // The number is too large to represent in a 64-bit value.
- err = errOverflow
- return
-}
-
-// DecodeFixed64 reads a 64-bit integer from the Buffer.
-// This is the format for the
-// fixed64, sfixed64, and double protocol buffer types.
-func (p *Buffer) DecodeFixed64() (x uint64, err error) {
- // x, err already 0
- i := p.index + 8
- if i < 0 || i > len(p.buf) {
- err = io.ErrUnexpectedEOF
- return
- }
- p.index = i
-
- x = uint64(p.buf[i-8])
- x |= uint64(p.buf[i-7]) << 8
- x |= uint64(p.buf[i-6]) << 16
- x |= uint64(p.buf[i-5]) << 24
- x |= uint64(p.buf[i-4]) << 32
- x |= uint64(p.buf[i-3]) << 40
- x |= uint64(p.buf[i-2]) << 48
- x |= uint64(p.buf[i-1]) << 56
- return
-}
-
-// DecodeFixed32 reads a 32-bit integer from the Buffer.
-// This is the format for the
-// fixed32, sfixed32, and float protocol buffer types.
-func (p *Buffer) DecodeFixed32() (x uint64, err error) {
- // x, err already 0
- i := p.index + 4
- if i < 0 || i > len(p.buf) {
- err = io.ErrUnexpectedEOF
- return
- }
- p.index = i
-
- x = uint64(p.buf[i-4])
- x |= uint64(p.buf[i-3]) << 8
- x |= uint64(p.buf[i-2]) << 16
- x |= uint64(p.buf[i-1]) << 24
- return
-}
-
-// DecodeZigzag64 reads a zigzag-encoded 64-bit integer
-// from the Buffer.
-// This is the format used for the sint64 protocol buffer type.
-func (p *Buffer) DecodeZigzag64() (x uint64, err error) {
- x, err = p.DecodeVarint()
- if err != nil {
- return
- }
- x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63)
- return
-}
-
-// DecodeZigzag32 reads a zigzag-encoded 32-bit integer
-// from the Buffer.
-// This is the format used for the sint32 protocol buffer type.
-func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
- x, err = p.DecodeVarint()
- if err != nil {
- return
- }
- x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31))
- return
-}
-
-// These are not ValueDecoders: they produce an array of bytes or a string.
-// bytes, embedded messages
-
-// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
-// This is the format used for the bytes protocol buffer
-// type and for embedded messages.
-func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
- n, err := p.DecodeVarint()
- if err != nil {
- return nil, err
- }
-
- nb := int(n)
- if nb < 0 {
- return nil, fmt.Errorf("proto: bad byte length %d", nb)
- }
- end := p.index + nb
- if end < p.index || end > len(p.buf) {
- return nil, io.ErrUnexpectedEOF
- }
-
- if !alloc {
- // todo: check if can get more uses of alloc=false
- buf = p.buf[p.index:end]
- p.index += nb
- return
- }
-
- buf = make([]byte, nb)
- copy(buf, p.buf[p.index:])
- p.index += nb
- return
-}
-
-// DecodeStringBytes reads an encoded string from the Buffer.
-// This is the format used for the proto2 string type.
-func (p *Buffer) DecodeStringBytes() (s string, err error) {
- buf, err := p.DecodeRawBytes(false)
- if err != nil {
- return
- }
- return string(buf), nil
-}
-
-// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
-// If the protocol buffer has extensions, and the field matches, add it as an extension.
-// Otherwise, if the XXX_unrecognized field exists, append the skipped data there.
-func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base structPointer, unrecField field) error {
- oi := o.index
-
- err := o.skip(t, tag, wire)
- if err != nil {
- return err
- }
-
- if !unrecField.IsValid() {
- return nil
- }
-
- ptr := structPointer_Bytes(base, unrecField)
-
- // Add the skipped field to struct field
- obuf := o.buf
-
- o.buf = *ptr
- o.EncodeVarint(uint64(tag<<3 | wire))
- *ptr = append(o.buf, obuf[oi:o.index]...)
-
- o.buf = obuf
-
- return nil
-}
-
-// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
-func (o *Buffer) skip(t reflect.Type, tag, wire int) error {
-
- var u uint64
- var err error
-
- switch wire {
- case WireVarint:
- _, err = o.DecodeVarint()
- case WireFixed64:
- _, err = o.DecodeFixed64()
- case WireBytes:
- _, err = o.DecodeRawBytes(false)
- case WireFixed32:
- _, err = o.DecodeFixed32()
- case WireStartGroup:
- for {
- u, err = o.DecodeVarint()
- if err != nil {
- break
- }
- fwire := int(u & 0x7)
- if fwire == WireEndGroup {
- break
- }
- ftag := int(u >> 3)
- err = o.skip(t, ftag, fwire)
- if err != nil {
- break
- }
- }
- default:
- err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t)
- }
- return err
-}
-
-// Unmarshaler is the interface representing objects that can
-// unmarshal themselves. The method should reset the receiver before
-// decoding starts. The argument points to data that may be
-// overwritten, so implementations should not keep references to the
-// buffer.
-type Unmarshaler interface {
- Unmarshal([]byte) error
-}
-
-// Unmarshal parses the protocol buffer representation in buf and places the
-// decoded result in pb. If the struct underlying pb does not match
-// the data in buf, the results can be unpredictable.
-//
-// Unmarshal resets pb before starting to unmarshal, so any
-// existing data in pb is always removed. Use UnmarshalMerge
-// to preserve and append to existing data.
-func Unmarshal(buf []byte, pb Message) error {
- pb.Reset()
- return UnmarshalMerge(buf, pb)
-}
-
-// UnmarshalMerge parses the protocol buffer representation in buf and
-// writes the decoded result to pb. If the struct underlying pb does not match
-// the data in buf, the results can be unpredictable.
-//
-// UnmarshalMerge merges into existing data in pb.
-// Most code should use Unmarshal instead.
-func UnmarshalMerge(buf []byte, pb Message) error {
- // If the object can unmarshal itself, let it.
- if u, ok := pb.(Unmarshaler); ok {
- return u.Unmarshal(buf)
- }
- return NewBuffer(buf).Unmarshal(pb)
-}
-
-// Unmarshal parses the protocol buffer representation in the
-// Buffer and places the decoded result in pb. If the struct
-// underlying pb does not match the data in the buffer, the results can be
-// unpredictable.
-func (p *Buffer) Unmarshal(pb Message) error {
- // If the object can unmarshal itself, let it.
- if u, ok := pb.(Unmarshaler); ok {
- err := u.Unmarshal(p.buf[p.index:])
- p.index = len(p.buf)
- return err
- }
-
- typ, base, err := getbase(pb)
- if err != nil {
- return err
- }
-
- err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base)
-
- if collectStats {
- stats.Decode++
- }
-
- return err
-}
-
-// unmarshalType does the work of unmarshaling a structure.
-func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error {
- var state errorState
- required, reqFields := prop.reqCount, uint64(0)
-
- var err error
- for err == nil && o.index < len(o.buf) {
- oi := o.index
- var u uint64
- u, err = o.DecodeVarint()
- if err != nil {
- break
- }
- wire := int(u & 0x7)
- if wire == WireEndGroup {
- if is_group {
- return nil // input is satisfied
- }
- return fmt.Errorf("proto: %s: wiretype end group for non-group", st)
- }
- tag := int(u >> 3)
- if tag <= 0 {
- return fmt.Errorf("proto: %s: illegal tag %d (wire type %d)", st, tag, wire)
- }
- fieldnum, ok := prop.decoderTags.get(tag)
- if !ok {
- // Maybe it's an extension?
- if prop.extendable {
- if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) {
- if err = o.skip(st, tag, wire); err == nil {
- ext := e.ExtensionMap()[int32(tag)] // may be missing
- ext.enc = append(ext.enc, o.buf[oi:o.index]...)
- e.ExtensionMap()[int32(tag)] = ext
- }
- continue
- }
- }
- err = o.skipAndSave(st, tag, wire, base, prop.unrecField)
- continue
- }
- p := prop.Prop[fieldnum]
-
- if p.dec == nil {
- fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name)
- continue
- }
- dec := p.dec
- if wire != WireStartGroup && wire != p.WireType {
- if wire == WireBytes && p.packedDec != nil {
- // a packable field
- dec = p.packedDec
- } else {
- err = fmt.Errorf("proto: bad wiretype for field %s.%s: got wiretype %d, want %d", st, st.Field(fieldnum).Name, wire, p.WireType)
- continue
- }
- }
- decErr := dec(o, p, base)
- if decErr != nil && !state.shouldContinue(decErr, p) {
- err = decErr
- }
- if err == nil && p.Required {
- // Successfully decoded a required field.
- if tag <= 64 {
- // use bitmap for fields 1-64 to catch field reuse.
- var mask uint64 = 1 << uint64(tag-1)
- if reqFields&mask == 0 {
- // new required field
- reqFields |= mask
- required--
- }
- } else {
- // This is imprecise. It can be fooled by a required field
- // with a tag > 64 that is encoded twice; that's very rare.
- // A fully correct implementation would require allocating
- // a data structure, which we would like to avoid.
- required--
- }
- }
- }
- if err == nil {
- if is_group {
- return io.ErrUnexpectedEOF
- }
- if state.err != nil {
- return state.err
- }
- if required > 0 {
- // Not enough information to determine the exact field. If we use extra
- // CPU, we could determine the field only if the missing required field
- // has a tag <= 64 and we check reqFields.
- return &RequiredNotSetError{"{Unknown}"}
- }
- }
- return err
-}
-
-// Individual type decoders
-// For each,
-// u is the decoded value,
-// v is a pointer to the field (pointer) in the struct
-
-// Sizes of the pools to allocate inside the Buffer.
-// The goal is modest amortization and allocation
-// on at least 16-byte boundaries.
-const (
- boolPoolSize = 16
- uint32PoolSize = 8
- uint64PoolSize = 4
-)
-
-// Decode a bool.
-func (o *Buffer) dec_bool(p *Properties, base structPointer) error {
- u, err := p.valDec(o)
- if err != nil {
- return err
- }
- if len(o.bools) == 0 {
- o.bools = make([]bool, boolPoolSize)
- }
- o.bools[0] = u != 0
- *structPointer_Bool(base, p.field) = &o.bools[0]
- o.bools = o.bools[1:]
- return nil
-}
-
-func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error {
- u, err := p.valDec(o)
- if err != nil {
- return err
- }
- *structPointer_BoolVal(base, p.field) = u != 0
- return nil
-}
-
-// Decode an int32.
-func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
- u, err := p.valDec(o)
- if err != nil {
- return err
- }
- word32_Set(structPointer_Word32(base, p.field), o, uint32(u))
- return nil
-}
-
-func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error {
- u, err := p.valDec(o)
- if err != nil {
- return err
- }
- word32Val_Set(structPointer_Word32Val(base, p.field), uint32(u))
- return nil
-}
-
-// Decode an int64.
-func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
- u, err := p.valDec(o)
- if err != nil {
- return err
- }
- word64_Set(structPointer_Word64(base, p.field), o, u)
- return nil
-}
-
-func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error {
- u, err := p.valDec(o)
- if err != nil {
- return err
- }
- word64Val_Set(structPointer_Word64Val(base, p.field), o, u)
- return nil
-}
-
-// Decode a string.
-func (o *Buffer) dec_string(p *Properties, base structPointer) error {
- s, err := o.DecodeStringBytes()
- if err != nil {
- return err
- }
- *structPointer_String(base, p.field) = &s
- return nil
-}
-
-func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error {
- s, err := o.DecodeStringBytes()
- if err != nil {
- return err
- }
- *structPointer_StringVal(base, p.field) = s
- return nil
-}
-
-// Decode a slice of bytes ([]byte).
-func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error {
- b, err := o.DecodeRawBytes(true)
- if err != nil {
- return err
- }
- *structPointer_Bytes(base, p.field) = b
- return nil
-}
-
-// Decode a slice of bools ([]bool).
-func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error {
- u, err := p.valDec(o)
- if err != nil {
- return err
- }
- v := structPointer_BoolSlice(base, p.field)
- *v = append(*v, u != 0)
- return nil
-}
-
-// Decode a slice of bools ([]bool) in packed format.
-func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error {
- v := structPointer_BoolSlice(base, p.field)
-
- nn, err := o.DecodeVarint()
- if err != nil {
- return err
- }
- nb := int(nn) // number of bytes of encoded bools
-
- y := *v
- for i := 0; i < nb; i++ {
- u, err := p.valDec(o)
- if err != nil {
- return err
- }
- y = append(y, u != 0)
- }
-
- *v = y
- return nil
-}
-
-// Decode a slice of int32s ([]int32).
-func (o *Buffer) dec_slice_int32(p *Properties, base structPointer) error {
- u, err := p.valDec(o)
- if err != nil {
- return err
- }
- structPointer_Word32Slice(base, p.field).Append(uint32(u))
- return nil
-}
-
-// Decode a slice of int32s ([]int32) in packed format.
-func (o *Buffer) dec_slice_packed_int32(p *Properties, base structPointer) error {
- v := structPointer_Word32Slice(base, p.field)
-
- nn, err := o.DecodeVarint()
- if err != nil {
- return err
- }
- nb := int(nn) // number of bytes of encoded int32s
-
- fin := o.index + nb
- if fin < o.index {
- return errOverflow
- }
- for o.index < fin {
- u, err := p.valDec(o)
- if err != nil {
- return err
- }
- v.Append(uint32(u))
- }
- return nil
-}
-
-// Decode a slice of int64s ([]int64).
-func (o *Buffer) dec_slice_int64(p *Properties, base structPointer) error {
- u, err := p.valDec(o)
- if err != nil {
- return err
- }
-
- structPointer_Word64Slice(base, p.field).Append(u)
- return nil
-}
-
-// Decode a slice of int64s ([]int64) in packed format.
-func (o *Buffer) dec_slice_packed_int64(p *Properties, base structPointer) error {
- v := structPointer_Word64Slice(base, p.field)
-
- nn, err := o.DecodeVarint()
- if err != nil {
- return err
- }
- nb := int(nn) // number of bytes of encoded int64s
-
- fin := o.index + nb
- if fin < o.index {
- return errOverflow
- }
- for o.index < fin {
- u, err := p.valDec(o)
- if err != nil {
- return err
- }
- v.Append(u)
- }
- return nil
-}
-
-// Decode a slice of strings ([]string).
-func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error {
- s, err := o.DecodeStringBytes()
- if err != nil {
- return err
- }
- v := structPointer_StringSlice(base, p.field)
- *v = append(*v, s)
- return nil
-}
-
-// Decode a slice of slice of bytes ([][]byte).
-func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error {
- b, err := o.DecodeRawBytes(true)
- if err != nil {
- return err
- }
- v := structPointer_BytesSlice(base, p.field)
- *v = append(*v, b)
- return nil
-}
-
-// Decode a map field.
-func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
- raw, err := o.DecodeRawBytes(false)
- if err != nil {
- return err
- }
- oi := o.index // index at the end of this map entry
- o.index -= len(raw) // move buffer back to start of map entry
-
- mptr := structPointer_Map(base, p.field, p.mtype) // *map[K]V
- if mptr.Elem().IsNil() {
- mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem()))
- }
- v := mptr.Elem() // map[K]V
-
- // Prepare addressable doubly-indirect placeholders for the key and value types.
- // See enc_new_map for why.
- keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K
- keybase := toStructPointer(keyptr.Addr()) // **K
-
- var valbase structPointer
- var valptr reflect.Value
- switch p.mtype.Elem().Kind() {
- case reflect.Slice:
- // []byte
- var dummy []byte
- valptr = reflect.ValueOf(&dummy) // *[]byte
- valbase = toStructPointer(valptr) // *[]byte
- case reflect.Ptr:
- // message; valptr is **Msg; need to allocate the intermediate pointer
- valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
- valptr.Set(reflect.New(valptr.Type().Elem()))
- valbase = toStructPointer(valptr)
- default:
- // everything else
- valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
- valbase = toStructPointer(valptr.Addr()) // **V
- }
-
- // Decode.
- // This parses a restricted wire format, namely the encoding of a message
- // with two fields. See enc_new_map for the format.
- for o.index < oi {
- // tagcode for key and value properties are always a single byte
- // because they have tags 1 and 2.
- tagcode := o.buf[o.index]
- o.index++
- switch tagcode {
- case p.mkeyprop.tagcode[0]:
- if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil {
- return err
- }
- case p.mvalprop.tagcode[0]:
- if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil {
- return err
- }
- default:
- // TODO: Should we silently skip this instead?
- return fmt.Errorf("proto: bad map data tag %d", raw[0])
- }
- }
-
- v.SetMapIndex(keyptr.Elem(), valptr.Elem())
- return nil
-}
-
-// Decode a group.
-func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error {
- bas := structPointer_GetStructPointer(base, p.field)
- if structPointer_IsNil(bas) {
- // allocate new nested message
- bas = toStructPointer(reflect.New(p.stype))
- structPointer_SetStructPointer(base, p.field, bas)
- }
- return o.unmarshalType(p.stype, p.sprop, true, bas)
-}
-
-// Decode an embedded message.
-func (o *Buffer) dec_struct_message(p *Properties, base structPointer) (err error) {
- raw, e := o.DecodeRawBytes(false)
- if e != nil {
- return e
- }
-
- bas := structPointer_GetStructPointer(base, p.field)
- if structPointer_IsNil(bas) {
- // allocate new nested message
- bas = toStructPointer(reflect.New(p.stype))
- structPointer_SetStructPointer(base, p.field, bas)
- }
-
- // If the object can unmarshal itself, let it.
- if p.isUnmarshaler {
- iv := structPointer_Interface(bas, p.stype)
- return iv.(Unmarshaler).Unmarshal(raw)
- }
-
- obuf := o.buf
- oi := o.index
- o.buf = raw
- o.index = 0
-
- err = o.unmarshalType(p.stype, p.sprop, false, bas)
- o.buf = obuf
- o.index = oi
-
- return err
-}
-
-// Decode a slice of embedded messages.
-func (o *Buffer) dec_slice_struct_message(p *Properties, base structPointer) error {
- return o.dec_slice_struct(p, false, base)
-}
-
-// Decode a slice of embedded groups.
-func (o *Buffer) dec_slice_struct_group(p *Properties, base structPointer) error {
- return o.dec_slice_struct(p, true, base)
-}
-
-// Decode a slice of structs ([]*struct).
-func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base structPointer) error {
- v := reflect.New(p.stype)
- bas := toStructPointer(v)
- structPointer_StructPointerSlice(base, p.field).Append(bas)
-
- if is_group {
- err := o.unmarshalType(p.stype, p.sprop, is_group, bas)
- return err
- }
-
- raw, err := o.DecodeRawBytes(false)
- if err != nil {
- return err
- }
-
- // If the object can unmarshal itself, let it.
- if p.isUnmarshaler {
- iv := v.Interface()
- return iv.(Unmarshaler).Unmarshal(raw)
- }
-
- obuf := o.buf
- oi := o.index
- o.buf = raw
- o.index = 0
-
- err = o.unmarshalType(p.stype, p.sprop, is_group, bas)
-
- o.buf = obuf
- o.index = oi
-
- return err
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/encode.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/encode.go
deleted file mode 100644
index cd826e9b..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/encode.go
+++ /dev/null
@@ -1,1286 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2010 The Go Authors. All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package proto
-
-/*
- * Routines for encoding data into the wire format for protocol buffers.
- */
-
-import (
- "errors"
- "fmt"
- "reflect"
- "sort"
-)
-
-// RequiredNotSetError is the error returned if Marshal is called with
-// a protocol buffer struct whose required fields have not
-// all been initialized. It is also the error returned if Unmarshal is
-// called with an encoded protocol buffer that does not include all the
-// required fields.
-//
-// When printed, RequiredNotSetError reports the first unset required field in a
-// message. If the field cannot be precisely determined, it is reported as
-// "{Unknown}".
-type RequiredNotSetError struct {
- field string
-}
-
-func (e *RequiredNotSetError) Error() string {
- return fmt.Sprintf("proto: required field %q not set", e.field)
-}
-
-var (
- // errRepeatedHasNil is the error returned if Marshal is called with
- // a struct with a repeated field containing a nil element.
- errRepeatedHasNil = errors.New("proto: repeated field has nil element")
-
- // ErrNil is the error returned if Marshal is called with nil.
- ErrNil = errors.New("proto: Marshal called with nil")
-)
-
-// The fundamental encoders that put bytes on the wire.
-// Those that take integer types all accept uint64 and are
-// therefore of type valueEncoder.
-
-const maxVarintBytes = 10 // maximum length of a varint
-
-// EncodeVarint returns the varint encoding of x.
-// This is the format for the
-// int32, int64, uint32, uint64, bool, and enum
-// protocol buffer types.
-// Not used by the package itself, but helpful to clients
-// wishing to use the same encoding.
-func EncodeVarint(x uint64) []byte {
- var buf [maxVarintBytes]byte
- var n int
- for n = 0; x > 127; n++ {
- buf[n] = 0x80 | uint8(x&0x7F)
- x >>= 7
- }
- buf[n] = uint8(x)
- n++
- return buf[0:n]
-}
-
-// EncodeVarint writes a varint-encoded integer to the Buffer.
-// This is the format for the
-// int32, int64, uint32, uint64, bool, and enum
-// protocol buffer types.
-func (p *Buffer) EncodeVarint(x uint64) error {
- for x >= 1<<7 {
- p.buf = append(p.buf, uint8(x&0x7f|0x80))
- x >>= 7
- }
- p.buf = append(p.buf, uint8(x))
- return nil
-}
-
-func sizeVarint(x uint64) (n int) {
- for {
- n++
- x >>= 7
- if x == 0 {
- break
- }
- }
- return n
-}
-
-// EncodeFixed64 writes a 64-bit integer to the Buffer.
-// This is the format for the
-// fixed64, sfixed64, and double protocol buffer types.
-func (p *Buffer) EncodeFixed64(x uint64) error {
- p.buf = append(p.buf,
- uint8(x),
- uint8(x>>8),
- uint8(x>>16),
- uint8(x>>24),
- uint8(x>>32),
- uint8(x>>40),
- uint8(x>>48),
- uint8(x>>56))
- return nil
-}
-
-func sizeFixed64(x uint64) int {
- return 8
-}
-
-// EncodeFixed32 writes a 32-bit integer to the Buffer.
-// This is the format for the
-// fixed32, sfixed32, and float protocol buffer types.
-func (p *Buffer) EncodeFixed32(x uint64) error {
- p.buf = append(p.buf,
- uint8(x),
- uint8(x>>8),
- uint8(x>>16),
- uint8(x>>24))
- return nil
-}
-
-func sizeFixed32(x uint64) int {
- return 4
-}
-
-// EncodeZigzag64 writes a zigzag-encoded 64-bit integer
-// to the Buffer.
-// This is the format used for the sint64 protocol buffer type.
-func (p *Buffer) EncodeZigzag64(x uint64) error {
- // use signed number to get arithmetic right shift.
- return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
-}
-
-func sizeZigzag64(x uint64) int {
- return sizeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
-}
-
-// EncodeZigzag32 writes a zigzag-encoded 32-bit integer
-// to the Buffer.
-// This is the format used for the sint32 protocol buffer type.
-func (p *Buffer) EncodeZigzag32(x uint64) error {
- // use signed number to get arithmetic right shift.
- return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
-}
-
-func sizeZigzag32(x uint64) int {
- return sizeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
-}
-
-// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
-// This is the format used for the bytes protocol buffer
-// type and for embedded messages.
-func (p *Buffer) EncodeRawBytes(b []byte) error {
- p.EncodeVarint(uint64(len(b)))
- p.buf = append(p.buf, b...)
- return nil
-}
-
-func sizeRawBytes(b []byte) int {
- return sizeVarint(uint64(len(b))) +
- len(b)
-}
-
-// EncodeStringBytes writes an encoded string to the Buffer.
-// This is the format used for the proto2 string type.
-func (p *Buffer) EncodeStringBytes(s string) error {
- p.EncodeVarint(uint64(len(s)))
- p.buf = append(p.buf, s...)
- return nil
-}
-
-func sizeStringBytes(s string) int {
- return sizeVarint(uint64(len(s))) +
- len(s)
-}
-
-// Marshaler is the interface representing objects that can marshal themselves.
-type Marshaler interface {
- Marshal() ([]byte, error)
-}
-
-// Marshal takes the protocol buffer
-// and encodes it into the wire format, returning the data.
-func Marshal(pb Message) ([]byte, error) {
- // Can the object marshal itself?
- if m, ok := pb.(Marshaler); ok {
- return m.Marshal()
- }
- p := NewBuffer(nil)
- err := p.Marshal(pb)
- var state errorState
- if err != nil && !state.shouldContinue(err, nil) {
- return nil, err
- }
- if p.buf == nil && err == nil {
- // Return a non-nil slice on success.
- return []byte{}, nil
- }
- return p.buf, err
-}
-
-// Marshal takes the protocol buffer
-// and encodes it into the wire format, writing the result to the
-// Buffer.
-func (p *Buffer) Marshal(pb Message) error {
- // Can the object marshal itself?
- if m, ok := pb.(Marshaler); ok {
- data, err := m.Marshal()
- if err != nil {
- return err
- }
- p.buf = append(p.buf, data...)
- return nil
- }
-
- t, base, err := getbase(pb)
- if structPointer_IsNil(base) {
- return ErrNil
- }
- if err == nil {
- err = p.enc_struct(GetProperties(t.Elem()), base)
- }
-
- if collectStats {
- stats.Encode++
- }
-
- return err
-}
-
-// Size returns the encoded size of a protocol buffer.
-func Size(pb Message) (n int) {
- // Can the object marshal itself? If so, Size is slow.
- // TODO: add Size to Marshaler, or add a Sizer interface.
- if m, ok := pb.(Marshaler); ok {
- b, _ := m.Marshal()
- return len(b)
- }
-
- t, base, err := getbase(pb)
- if structPointer_IsNil(base) {
- return 0
- }
- if err == nil {
- n = size_struct(GetProperties(t.Elem()), base)
- }
-
- if collectStats {
- stats.Size++
- }
-
- return
-}
-
-// Individual type encoders.
-
-// Encode a bool.
-func (o *Buffer) enc_bool(p *Properties, base structPointer) error {
- v := *structPointer_Bool(base, p.field)
- if v == nil {
- return ErrNil
- }
- x := 0
- if *v {
- x = 1
- }
- o.buf = append(o.buf, p.tagcode...)
- p.valEnc(o, uint64(x))
- return nil
-}
-
-func (o *Buffer) enc_proto3_bool(p *Properties, base structPointer) error {
- v := *structPointer_BoolVal(base, p.field)
- if !v {
- return ErrNil
- }
- o.buf = append(o.buf, p.tagcode...)
- p.valEnc(o, 1)
- return nil
-}
-
-func size_bool(p *Properties, base structPointer) int {
- v := *structPointer_Bool(base, p.field)
- if v == nil {
- return 0
- }
- return len(p.tagcode) + 1 // each bool takes exactly one byte
-}
-
-func size_proto3_bool(p *Properties, base structPointer) int {
- v := *structPointer_BoolVal(base, p.field)
- if !v {
- return 0
- }
- return len(p.tagcode) + 1 // each bool takes exactly one byte
-}
-
-// Encode an int32.
-func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
- v := structPointer_Word32(base, p.field)
- if word32_IsNil(v) {
- return ErrNil
- }
- x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
- o.buf = append(o.buf, p.tagcode...)
- p.valEnc(o, uint64(x))
- return nil
-}
-
-func (o *Buffer) enc_proto3_int32(p *Properties, base structPointer) error {
- v := structPointer_Word32Val(base, p.field)
- x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
- if x == 0 {
- return ErrNil
- }
- o.buf = append(o.buf, p.tagcode...)
- p.valEnc(o, uint64(x))
- return nil
-}
-
-func size_int32(p *Properties, base structPointer) (n int) {
- v := structPointer_Word32(base, p.field)
- if word32_IsNil(v) {
- return 0
- }
- x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
- n += len(p.tagcode)
- n += p.valSize(uint64(x))
- return
-}
-
-func size_proto3_int32(p *Properties, base structPointer) (n int) {
- v := structPointer_Word32Val(base, p.field)
- x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
- if x == 0 {
- return 0
- }
- n += len(p.tagcode)
- n += p.valSize(uint64(x))
- return
-}
-
-// Encode a uint32.
-// Exactly the same as int32, except for no sign extension.
-func (o *Buffer) enc_uint32(p *Properties, base structPointer) error {
- v := structPointer_Word32(base, p.field)
- if word32_IsNil(v) {
- return ErrNil
- }
- x := word32_Get(v)
- o.buf = append(o.buf, p.tagcode...)
- p.valEnc(o, uint64(x))
- return nil
-}
-
-func (o *Buffer) enc_proto3_uint32(p *Properties, base structPointer) error {
- v := structPointer_Word32Val(base, p.field)
- x := word32Val_Get(v)
- if x == 0 {
- return ErrNil
- }
- o.buf = append(o.buf, p.tagcode...)
- p.valEnc(o, uint64(x))
- return nil
-}
-
-func size_uint32(p *Properties, base structPointer) (n int) {
- v := structPointer_Word32(base, p.field)
- if word32_IsNil(v) {
- return 0
- }
- x := word32_Get(v)
- n += len(p.tagcode)
- n += p.valSize(uint64(x))
- return
-}
-
-func size_proto3_uint32(p *Properties, base structPointer) (n int) {
- v := structPointer_Word32Val(base, p.field)
- x := word32Val_Get(v)
- if x == 0 {
- return 0
- }
- n += len(p.tagcode)
- n += p.valSize(uint64(x))
- return
-}
-
-// Encode an int64.
-func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
- v := structPointer_Word64(base, p.field)
- if word64_IsNil(v) {
- return ErrNil
- }
- x := word64_Get(v)
- o.buf = append(o.buf, p.tagcode...)
- p.valEnc(o, x)
- return nil
-}
-
-func (o *Buffer) enc_proto3_int64(p *Properties, base structPointer) error {
- v := structPointer_Word64Val(base, p.field)
- x := word64Val_Get(v)
- if x == 0 {
- return ErrNil
- }
- o.buf = append(o.buf, p.tagcode...)
- p.valEnc(o, x)
- return nil
-}
-
-func size_int64(p *Properties, base structPointer) (n int) {
- v := structPointer_Word64(base, p.field)
- if word64_IsNil(v) {
- return 0
- }
- x := word64_Get(v)
- n += len(p.tagcode)
- n += p.valSize(x)
- return
-}
-
-func size_proto3_int64(p *Properties, base structPointer) (n int) {
- v := structPointer_Word64Val(base, p.field)
- x := word64Val_Get(v)
- if x == 0 {
- return 0
- }
- n += len(p.tagcode)
- n += p.valSize(x)
- return
-}
-
-// Encode a string.
-func (o *Buffer) enc_string(p *Properties, base structPointer) error {
- v := *structPointer_String(base, p.field)
- if v == nil {
- return ErrNil
- }
- x := *v
- o.buf = append(o.buf, p.tagcode...)
- o.EncodeStringBytes(x)
- return nil
-}
-
-func (o *Buffer) enc_proto3_string(p *Properties, base structPointer) error {
- v := *structPointer_StringVal(base, p.field)
- if v == "" {
- return ErrNil
- }
- o.buf = append(o.buf, p.tagcode...)
- o.EncodeStringBytes(v)
- return nil
-}
-
-func size_string(p *Properties, base structPointer) (n int) {
- v := *structPointer_String(base, p.field)
- if v == nil {
- return 0
- }
- x := *v
- n += len(p.tagcode)
- n += sizeStringBytes(x)
- return
-}
-
-func size_proto3_string(p *Properties, base structPointer) (n int) {
- v := *structPointer_StringVal(base, p.field)
- if v == "" {
- return 0
- }
- n += len(p.tagcode)
- n += sizeStringBytes(v)
- return
-}
-
-// All protocol buffer fields are nillable, but be careful.
-func isNil(v reflect.Value) bool {
- switch v.Kind() {
- case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
- return v.IsNil()
- }
- return false
-}
-
-// Encode a message struct.
-func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error {
- var state errorState
- structp := structPointer_GetStructPointer(base, p.field)
- if structPointer_IsNil(structp) {
- return ErrNil
- }
-
- // Can the object marshal itself?
- if p.isMarshaler {
- m := structPointer_Interface(structp, p.stype).(Marshaler)
- data, err := m.Marshal()
- if err != nil && !state.shouldContinue(err, nil) {
- return err
- }
- o.buf = append(o.buf, p.tagcode...)
- o.EncodeRawBytes(data)
- return nil
- }
-
- o.buf = append(o.buf, p.tagcode...)
- return o.enc_len_struct(p.sprop, structp, &state)
-}
-
-func size_struct_message(p *Properties, base structPointer) int {
- structp := structPointer_GetStructPointer(base, p.field)
- if structPointer_IsNil(structp) {
- return 0
- }
-
- // Can the object marshal itself?
- if p.isMarshaler {
- m := structPointer_Interface(structp, p.stype).(Marshaler)
- data, _ := m.Marshal()
- n0 := len(p.tagcode)
- n1 := sizeRawBytes(data)
- return n0 + n1
- }
-
- n0 := len(p.tagcode)
- n1 := size_struct(p.sprop, structp)
- n2 := sizeVarint(uint64(n1)) // size of encoded length
- return n0 + n1 + n2
-}
-
-// Encode a group struct.
-func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error {
- var state errorState
- b := structPointer_GetStructPointer(base, p.field)
- if structPointer_IsNil(b) {
- return ErrNil
- }
-
- o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
- err := o.enc_struct(p.sprop, b)
- if err != nil && !state.shouldContinue(err, nil) {
- return err
- }
- o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
- return state.err
-}
-
-func size_struct_group(p *Properties, base structPointer) (n int) {
- b := structPointer_GetStructPointer(base, p.field)
- if structPointer_IsNil(b) {
- return 0
- }
-
- n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup))
- n += size_struct(p.sprop, b)
- n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup))
- return
-}
-
-// Encode a slice of bools ([]bool).
-func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error {
- s := *structPointer_BoolSlice(base, p.field)
- l := len(s)
- if l == 0 {
- return ErrNil
- }
- for _, x := range s {
- o.buf = append(o.buf, p.tagcode...)
- v := uint64(0)
- if x {
- v = 1
- }
- p.valEnc(o, v)
- }
- return nil
-}
-
-func size_slice_bool(p *Properties, base structPointer) int {
- s := *structPointer_BoolSlice(base, p.field)
- l := len(s)
- if l == 0 {
- return 0
- }
- return l * (len(p.tagcode) + 1) // each bool takes exactly one byte
-}
-
-// Encode a slice of bools ([]bool) in packed format.
-func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error {
- s := *structPointer_BoolSlice(base, p.field)
- l := len(s)
- if l == 0 {
- return ErrNil
- }
- o.buf = append(o.buf, p.tagcode...)
- o.EncodeVarint(uint64(l)) // each bool takes exactly one byte
- for _, x := range s {
- v := uint64(0)
- if x {
- v = 1
- }
- p.valEnc(o, v)
- }
- return nil
-}
-
-func size_slice_packed_bool(p *Properties, base structPointer) (n int) {
- s := *structPointer_BoolSlice(base, p.field)
- l := len(s)
- if l == 0 {
- return 0
- }
- n += len(p.tagcode)
- n += sizeVarint(uint64(l))
- n += l // each bool takes exactly one byte
- return
-}
-
-// Encode a slice of bytes ([]byte).
-func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
- s := *structPointer_Bytes(base, p.field)
- if s == nil {
- return ErrNil
- }
- o.buf = append(o.buf, p.tagcode...)
- o.EncodeRawBytes(s)
- return nil
-}
-
-func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error {
- s := *structPointer_Bytes(base, p.field)
- if len(s) == 0 {
- return ErrNil
- }
- o.buf = append(o.buf, p.tagcode...)
- o.EncodeRawBytes(s)
- return nil
-}
-
-func size_slice_byte(p *Properties, base structPointer) (n int) {
- s := *structPointer_Bytes(base, p.field)
- if s == nil {
- return 0
- }
- n += len(p.tagcode)
- n += sizeRawBytes(s)
- return
-}
-
-func size_proto3_slice_byte(p *Properties, base structPointer) (n int) {
- s := *structPointer_Bytes(base, p.field)
- if len(s) == 0 {
- return 0
- }
- n += len(p.tagcode)
- n += sizeRawBytes(s)
- return
-}
-
-// Encode a slice of int32s ([]int32).
-func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
- s := structPointer_Word32Slice(base, p.field)
- l := s.Len()
- if l == 0 {
- return ErrNil
- }
- for i := 0; i < l; i++ {
- o.buf = append(o.buf, p.tagcode...)
- x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
- p.valEnc(o, uint64(x))
- }
- return nil
-}
-
-func size_slice_int32(p *Properties, base structPointer) (n int) {
- s := structPointer_Word32Slice(base, p.field)
- l := s.Len()
- if l == 0 {
- return 0
- }
- for i := 0; i < l; i++ {
- n += len(p.tagcode)
- x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
- n += p.valSize(uint64(x))
- }
- return
-}
-
-// Encode a slice of int32s ([]int32) in packed format.
-func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error {
- s := structPointer_Word32Slice(base, p.field)
- l := s.Len()
- if l == 0 {
- return ErrNil
- }
- // TODO: Reuse a Buffer.
- buf := NewBuffer(nil)
- for i := 0; i < l; i++ {
- x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
- p.valEnc(buf, uint64(x))
- }
-
- o.buf = append(o.buf, p.tagcode...)
- o.EncodeVarint(uint64(len(buf.buf)))
- o.buf = append(o.buf, buf.buf...)
- return nil
-}
-
-func size_slice_packed_int32(p *Properties, base structPointer) (n int) {
- s := structPointer_Word32Slice(base, p.field)
- l := s.Len()
- if l == 0 {
- return 0
- }
- var bufSize int
- for i := 0; i < l; i++ {
- x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
- bufSize += p.valSize(uint64(x))
- }
-
- n += len(p.tagcode)
- n += sizeVarint(uint64(bufSize))
- n += bufSize
- return
-}
-
-// Encode a slice of uint32s ([]uint32).
-// Exactly the same as int32, except for no sign extension.
-func (o *Buffer) enc_slice_uint32(p *Properties, base structPointer) error {
- s := structPointer_Word32Slice(base, p.field)
- l := s.Len()
- if l == 0 {
- return ErrNil
- }
- for i := 0; i < l; i++ {
- o.buf = append(o.buf, p.tagcode...)
- x := s.Index(i)
- p.valEnc(o, uint64(x))
- }
- return nil
-}
-
-func size_slice_uint32(p *Properties, base structPointer) (n int) {
- s := structPointer_Word32Slice(base, p.field)
- l := s.Len()
- if l == 0 {
- return 0
- }
- for i := 0; i < l; i++ {
- n += len(p.tagcode)
- x := s.Index(i)
- n += p.valSize(uint64(x))
- }
- return
-}
-
-// Encode a slice of uint32s ([]uint32) in packed format.
-// Exactly the same as int32, except for no sign extension.
-func (o *Buffer) enc_slice_packed_uint32(p *Properties, base structPointer) error {
- s := structPointer_Word32Slice(base, p.field)
- l := s.Len()
- if l == 0 {
- return ErrNil
- }
- // TODO: Reuse a Buffer.
- buf := NewBuffer(nil)
- for i := 0; i < l; i++ {
- p.valEnc(buf, uint64(s.Index(i)))
- }
-
- o.buf = append(o.buf, p.tagcode...)
- o.EncodeVarint(uint64(len(buf.buf)))
- o.buf = append(o.buf, buf.buf...)
- return nil
-}
-
-func size_slice_packed_uint32(p *Properties, base structPointer) (n int) {
- s := structPointer_Word32Slice(base, p.field)
- l := s.Len()
- if l == 0 {
- return 0
- }
- var bufSize int
- for i := 0; i < l; i++ {
- bufSize += p.valSize(uint64(s.Index(i)))
- }
-
- n += len(p.tagcode)
- n += sizeVarint(uint64(bufSize))
- n += bufSize
- return
-}
-
-// Encode a slice of int64s ([]int64).
-func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error {
- s := structPointer_Word64Slice(base, p.field)
- l := s.Len()
- if l == 0 {
- return ErrNil
- }
- for i := 0; i < l; i++ {
- o.buf = append(o.buf, p.tagcode...)
- p.valEnc(o, s.Index(i))
- }
- return nil
-}
-
-func size_slice_int64(p *Properties, base structPointer) (n int) {
- s := structPointer_Word64Slice(base, p.field)
- l := s.Len()
- if l == 0 {
- return 0
- }
- for i := 0; i < l; i++ {
- n += len(p.tagcode)
- n += p.valSize(s.Index(i))
- }
- return
-}
-
-// Encode a slice of int64s ([]int64) in packed format.
-func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error {
- s := structPointer_Word64Slice(base, p.field)
- l := s.Len()
- if l == 0 {
- return ErrNil
- }
- // TODO: Reuse a Buffer.
- buf := NewBuffer(nil)
- for i := 0; i < l; i++ {
- p.valEnc(buf, s.Index(i))
- }
-
- o.buf = append(o.buf, p.tagcode...)
- o.EncodeVarint(uint64(len(buf.buf)))
- o.buf = append(o.buf, buf.buf...)
- return nil
-}
-
-func size_slice_packed_int64(p *Properties, base structPointer) (n int) {
- s := structPointer_Word64Slice(base, p.field)
- l := s.Len()
- if l == 0 {
- return 0
- }
- var bufSize int
- for i := 0; i < l; i++ {
- bufSize += p.valSize(s.Index(i))
- }
-
- n += len(p.tagcode)
- n += sizeVarint(uint64(bufSize))
- n += bufSize
- return
-}
-
-// Encode a slice of slice of bytes ([][]byte).
-func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error {
- ss := *structPointer_BytesSlice(base, p.field)
- l := len(ss)
- if l == 0 {
- return ErrNil
- }
- for i := 0; i < l; i++ {
- o.buf = append(o.buf, p.tagcode...)
- o.EncodeRawBytes(ss[i])
- }
- return nil
-}
-
-func size_slice_slice_byte(p *Properties, base structPointer) (n int) {
- ss := *structPointer_BytesSlice(base, p.field)
- l := len(ss)
- if l == 0 {
- return 0
- }
- n += l * len(p.tagcode)
- for i := 0; i < l; i++ {
- n += sizeRawBytes(ss[i])
- }
- return
-}
-
-// Encode a slice of strings ([]string).
-func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error {
- ss := *structPointer_StringSlice(base, p.field)
- l := len(ss)
- for i := 0; i < l; i++ {
- o.buf = append(o.buf, p.tagcode...)
- o.EncodeStringBytes(ss[i])
- }
- return nil
-}
-
-func size_slice_string(p *Properties, base structPointer) (n int) {
- ss := *structPointer_StringSlice(base, p.field)
- l := len(ss)
- n += l * len(p.tagcode)
- for i := 0; i < l; i++ {
- n += sizeStringBytes(ss[i])
- }
- return
-}
-
-// Encode a slice of message structs ([]*struct).
-func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error {
- var state errorState
- s := structPointer_StructPointerSlice(base, p.field)
- l := s.Len()
-
- for i := 0; i < l; i++ {
- structp := s.Index(i)
- if structPointer_IsNil(structp) {
- return errRepeatedHasNil
- }
-
- // Can the object marshal itself?
- if p.isMarshaler {
- m := structPointer_Interface(structp, p.stype).(Marshaler)
- data, err := m.Marshal()
- if err != nil && !state.shouldContinue(err, nil) {
- return err
- }
- o.buf = append(o.buf, p.tagcode...)
- o.EncodeRawBytes(data)
- continue
- }
-
- o.buf = append(o.buf, p.tagcode...)
- err := o.enc_len_struct(p.sprop, structp, &state)
- if err != nil && !state.shouldContinue(err, nil) {
- if err == ErrNil {
- return errRepeatedHasNil
- }
- return err
- }
- }
- return state.err
-}
-
-func size_slice_struct_message(p *Properties, base structPointer) (n int) {
- s := structPointer_StructPointerSlice(base, p.field)
- l := s.Len()
- n += l * len(p.tagcode)
- for i := 0; i < l; i++ {
- structp := s.Index(i)
- if structPointer_IsNil(structp) {
- return // return the size up to this point
- }
-
- // Can the object marshal itself?
- if p.isMarshaler {
- m := structPointer_Interface(structp, p.stype).(Marshaler)
- data, _ := m.Marshal()
- n += len(p.tagcode)
- n += sizeRawBytes(data)
- continue
- }
-
- n0 := size_struct(p.sprop, structp)
- n1 := sizeVarint(uint64(n0)) // size of encoded length
- n += n0 + n1
- }
- return
-}
-
-// Encode a slice of group structs ([]*struct).
-func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error {
- var state errorState
- s := structPointer_StructPointerSlice(base, p.field)
- l := s.Len()
-
- for i := 0; i < l; i++ {
- b := s.Index(i)
- if structPointer_IsNil(b) {
- return errRepeatedHasNil
- }
-
- o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
-
- err := o.enc_struct(p.sprop, b)
-
- if err != nil && !state.shouldContinue(err, nil) {
- if err == ErrNil {
- return errRepeatedHasNil
- }
- return err
- }
-
- o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
- }
- return state.err
-}
-
-func size_slice_struct_group(p *Properties, base structPointer) (n int) {
- s := structPointer_StructPointerSlice(base, p.field)
- l := s.Len()
-
- n += l * sizeVarint(uint64((p.Tag<<3)|WireStartGroup))
- n += l * sizeVarint(uint64((p.Tag<<3)|WireEndGroup))
- for i := 0; i < l; i++ {
- b := s.Index(i)
- if structPointer_IsNil(b) {
- return // return size up to this point
- }
-
- n += size_struct(p.sprop, b)
- }
- return
-}
-
-// Encode an extension map.
-func (o *Buffer) enc_map(p *Properties, base structPointer) error {
- v := *structPointer_ExtMap(base, p.field)
- if err := encodeExtensionMap(v); err != nil {
- return err
- }
- // Fast-path for common cases: zero or one extensions.
- if len(v) <= 1 {
- for _, e := range v {
- o.buf = append(o.buf, e.enc...)
- }
- return nil
- }
-
- // Sort keys to provide a deterministic encoding.
- keys := make([]int, 0, len(v))
- for k := range v {
- keys = append(keys, int(k))
- }
- sort.Ints(keys)
-
- for _, k := range keys {
- o.buf = append(o.buf, v[int32(k)].enc...)
- }
- return nil
-}
-
-func size_map(p *Properties, base structPointer) int {
- v := *structPointer_ExtMap(base, p.field)
- return sizeExtensionMap(v)
-}
-
-// Encode a map field.
-func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
- var state errorState // XXX: or do we need to plumb this through?
-
- /*
- A map defined as
- map map_field = N;
- is encoded in the same way as
- message MapFieldEntry {
- key_type key = 1;
- value_type value = 2;
- }
- repeated MapFieldEntry map_field = N;
- */
-
- v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V
- if v.Len() == 0 {
- return nil
- }
-
- keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
-
- enc := func() error {
- if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil {
- return err
- }
- if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil {
- return err
- }
- return nil
- }
-
- keys := v.MapKeys()
- sort.Sort(mapKeys(keys))
- for _, key := range keys {
- val := v.MapIndex(key)
-
- keycopy.Set(key)
- valcopy.Set(val)
-
- o.buf = append(o.buf, p.tagcode...)
- if err := o.enc_len_thing(enc, &state); err != nil {
- return err
- }
- }
- return nil
-}
-
-func size_new_map(p *Properties, base structPointer) int {
- v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V
-
- keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
-
- n := 0
- for _, key := range v.MapKeys() {
- val := v.MapIndex(key)
- keycopy.Set(key)
- valcopy.Set(val)
-
- // Tag codes are two bytes per map entry.
- n += 2
- n += p.mkeyprop.size(p.mkeyprop, keybase)
- n += p.mvalprop.size(p.mvalprop, valbase)
- }
- return n
-}
-
-// mapEncodeScratch returns a new reflect.Value matching the map's value type,
-// and a structPointer suitable for passing to an encoder or sizer.
-func mapEncodeScratch(mapType reflect.Type) (keycopy, valcopy reflect.Value, keybase, valbase structPointer) {
- // Prepare addressable doubly-indirect placeholders for the key and value types.
- // This is needed because the element-type encoders expect **T, but the map iteration produces T.
-
- keycopy = reflect.New(mapType.Key()).Elem() // addressable K
- keyptr := reflect.New(reflect.PtrTo(keycopy.Type())).Elem() // addressable *K
- keyptr.Set(keycopy.Addr()) //
- keybase = toStructPointer(keyptr.Addr()) // **K
-
- // Value types are more varied and require special handling.
- switch mapType.Elem().Kind() {
- case reflect.Slice:
- // []byte
- var dummy []byte
- valcopy = reflect.ValueOf(&dummy).Elem() // addressable []byte
- valbase = toStructPointer(valcopy.Addr())
- case reflect.Ptr:
- // message; the generated field type is map[K]*Msg (so V is *Msg),
- // so we only need one level of indirection.
- valcopy = reflect.New(mapType.Elem()).Elem() // addressable V
- valbase = toStructPointer(valcopy.Addr())
- default:
- // everything else
- valcopy = reflect.New(mapType.Elem()).Elem() // addressable V
- valptr := reflect.New(reflect.PtrTo(valcopy.Type())).Elem() // addressable *V
- valptr.Set(valcopy.Addr()) //
- valbase = toStructPointer(valptr.Addr()) // **V
- }
- return
-}
-
-// Encode a struct.
-func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
- var state errorState
- // Encode fields in tag order so that decoders may use optimizations
- // that depend on the ordering.
- // https://developers.google.com/protocol-buffers/docs/encoding#order
- for _, i := range prop.order {
- p := prop.Prop[i]
- if p.enc != nil {
- err := p.enc(o, p, base)
- if err != nil {
- if err == ErrNil {
- if p.Required && state.err == nil {
- state.err = &RequiredNotSetError{p.Name}
- }
- } else if err == errRepeatedHasNil {
- // Give more context to nil values in repeated fields.
- return errors.New("repeated field " + p.OrigName + " has nil element")
- } else if !state.shouldContinue(err, p) {
- return err
- }
- }
- }
- }
-
- // Add unrecognized fields at the end.
- if prop.unrecField.IsValid() {
- v := *structPointer_Bytes(base, prop.unrecField)
- if len(v) > 0 {
- o.buf = append(o.buf, v...)
- }
- }
-
- return state.err
-}
-
-func size_struct(prop *StructProperties, base structPointer) (n int) {
- for _, i := range prop.order {
- p := prop.Prop[i]
- if p.size != nil {
- n += p.size(p, base)
- }
- }
-
- // Add unrecognized fields at the end.
- if prop.unrecField.IsValid() {
- v := *structPointer_Bytes(base, prop.unrecField)
- n += len(v)
- }
-
- return
-}
-
-var zeroes [20]byte // longer than any conceivable sizeVarint
-
-// Encode a struct, preceded by its encoded length (as a varint).
-func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error {
- return o.enc_len_thing(func() error { return o.enc_struct(prop, base) }, state)
-}
-
-// Encode something, preceded by its encoded length (as a varint).
-func (o *Buffer) enc_len_thing(enc func() error, state *errorState) error {
- iLen := len(o.buf)
- o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length
- iMsg := len(o.buf)
- err := enc()
- if err != nil && !state.shouldContinue(err, nil) {
- return err
- }
- lMsg := len(o.buf) - iMsg
- lLen := sizeVarint(uint64(lMsg))
- switch x := lLen - (iMsg - iLen); {
- case x > 0: // actual length is x bytes larger than the space we reserved
- // Move msg x bytes right.
- o.buf = append(o.buf, zeroes[:x]...)
- copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
- case x < 0: // actual length is x bytes smaller than the space we reserved
- // Move msg x bytes left.
- copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
- o.buf = o.buf[:len(o.buf)+x] // x is negative
- }
- // Encode the length in the reserved space.
- o.buf = o.buf[:iLen]
- o.EncodeVarint(uint64(lMsg))
- o.buf = o.buf[:len(o.buf)+lMsg]
- return state.err
-}
-
-// errorState maintains the first error that occurs and updates that error
-// with additional context.
-type errorState struct {
- err error
-}
-
-// shouldContinue reports whether encoding should continue upon encountering the
-// given error. If the error is RequiredNotSetError, shouldContinue returns true
-// and, if this is the first appearance of that error, remembers it for future
-// reporting.
-//
-// If prop is not nil, it may update any error with additional context about the
-// field with the error.
-func (s *errorState) shouldContinue(err error, prop *Properties) bool {
- // Ignore unset required fields.
- reqNotSet, ok := err.(*RequiredNotSetError)
- if !ok {
- return false
- }
- if s.err == nil {
- if prop != nil {
- err = &RequiredNotSetError{prop.Name + "." + reqNotSet.field}
- }
- s.err = err
- }
- return true
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/equal.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/equal.go
deleted file mode 100644
index d8673a3e..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/equal.go
+++ /dev/null
@@ -1,256 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2011 The Go Authors. All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Protocol buffer comparison.
-// TODO: MessageSet.
-
-package proto
-
-import (
- "bytes"
- "log"
- "reflect"
- "strings"
-)
-
-/*
-Equal returns true iff protocol buffers a and b are equal.
-The arguments must both be pointers to protocol buffer structs.
-
-Equality is defined in this way:
- - Two messages are equal iff they are the same type,
- corresponding fields are equal, unknown field sets
- are equal, and extensions sets are equal.
- - Two set scalar fields are equal iff their values are equal.
- If the fields are of a floating-point type, remember that
- NaN != x for all x, including NaN.
- - Two repeated fields are equal iff their lengths are the same,
- and their corresponding elements are equal (a "bytes" field,
- although represented by []byte, is not a repeated field)
- - Two unset fields are equal.
- - Two unknown field sets are equal if their current
- encoded state is equal.
- - Two extension sets are equal iff they have corresponding
- elements that are pairwise equal.
- - Every other combination of things are not equal.
-
-The return value is undefined if a and b are not protocol buffers.
-*/
-func Equal(a, b Message) bool {
- if a == nil || b == nil {
- return a == b
- }
- v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b)
- if v1.Type() != v2.Type() {
- return false
- }
- if v1.Kind() == reflect.Ptr {
- if v1.IsNil() {
- return v2.IsNil()
- }
- if v2.IsNil() {
- return false
- }
- v1, v2 = v1.Elem(), v2.Elem()
- }
- if v1.Kind() != reflect.Struct {
- return false
- }
- return equalStruct(v1, v2)
-}
-
-// v1 and v2 are known to have the same type.
-func equalStruct(v1, v2 reflect.Value) bool {
- for i := 0; i < v1.NumField(); i++ {
- f := v1.Type().Field(i)
- if strings.HasPrefix(f.Name, "XXX_") {
- continue
- }
- f1, f2 := v1.Field(i), v2.Field(i)
- if f.Type.Kind() == reflect.Ptr {
- if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 {
- // both unset
- continue
- } else if n1 != n2 {
- // set/unset mismatch
- return false
- }
- b1, ok := f1.Interface().(raw)
- if ok {
- b2 := f2.Interface().(raw)
- // RawMessage
- if !bytes.Equal(b1.Bytes(), b2.Bytes()) {
- return false
- }
- continue
- }
- f1, f2 = f1.Elem(), f2.Elem()
- }
- if !equalAny(f1, f2) {
- return false
- }
- }
-
- if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() {
- em2 := v2.FieldByName("XXX_extensions")
- if !equalExtensions(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) {
- return false
- }
- }
-
- uf := v1.FieldByName("XXX_unrecognized")
- if !uf.IsValid() {
- return true
- }
-
- u1 := uf.Bytes()
- u2 := v2.FieldByName("XXX_unrecognized").Bytes()
- if !bytes.Equal(u1, u2) {
- return false
- }
-
- return true
-}
-
-// v1 and v2 are known to have the same type.
-func equalAny(v1, v2 reflect.Value) bool {
- if v1.Type() == protoMessageType {
- m1, _ := v1.Interface().(Message)
- m2, _ := v2.Interface().(Message)
- return Equal(m1, m2)
- }
- switch v1.Kind() {
- case reflect.Bool:
- return v1.Bool() == v2.Bool()
- case reflect.Float32, reflect.Float64:
- return v1.Float() == v2.Float()
- case reflect.Int32, reflect.Int64:
- return v1.Int() == v2.Int()
- case reflect.Map:
- if v1.Len() != v2.Len() {
- return false
- }
- for _, key := range v1.MapKeys() {
- val2 := v2.MapIndex(key)
- if !val2.IsValid() {
- // This key was not found in the second map.
- return false
- }
- if !equalAny(v1.MapIndex(key), val2) {
- return false
- }
- }
- return true
- case reflect.Ptr:
- return equalAny(v1.Elem(), v2.Elem())
- case reflect.Slice:
- if v1.Type().Elem().Kind() == reflect.Uint8 {
- // short circuit: []byte
- if v1.IsNil() != v2.IsNil() {
- return false
- }
- return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte))
- }
-
- if v1.Len() != v2.Len() {
- return false
- }
- for i := 0; i < v1.Len(); i++ {
- if !equalAny(v1.Index(i), v2.Index(i)) {
- return false
- }
- }
- return true
- case reflect.String:
- return v1.Interface().(string) == v2.Interface().(string)
- case reflect.Struct:
- return equalStruct(v1, v2)
- case reflect.Uint32, reflect.Uint64:
- return v1.Uint() == v2.Uint()
- }
-
- // unknown type, so not a protocol buffer
- log.Printf("proto: don't know how to compare %v", v1)
- return false
-}
-
-// base is the struct type that the extensions are based on.
-// em1 and em2 are extension maps.
-func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool {
- if len(em1) != len(em2) {
- return false
- }
-
- for extNum, e1 := range em1 {
- e2, ok := em2[extNum]
- if !ok {
- return false
- }
-
- m1, m2 := e1.value, e2.value
-
- if m1 != nil && m2 != nil {
- // Both are unencoded.
- if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2)) {
- return false
- }
- continue
- }
-
- // At least one is encoded. To do a semantically correct comparison
- // we need to unmarshal them first.
- var desc *ExtensionDesc
- if m := extensionMaps[base]; m != nil {
- desc = m[extNum]
- }
- if desc == nil {
- log.Printf("proto: don't know how to compare extension %d of %v", extNum, base)
- continue
- }
- var err error
- if m1 == nil {
- m1, err = decodeExtension(e1.enc, desc)
- }
- if m2 == nil && err == nil {
- m2, err = decodeExtension(e2.enc, desc)
- }
- if err != nil {
- // The encoded form is invalid.
- log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err)
- return false
- }
- if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2)) {
- return false
- }
- }
-
- return true
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/extensions.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/extensions.go
deleted file mode 100644
index 5f62dff2..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/extensions.go
+++ /dev/null
@@ -1,362 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2010 The Go Authors. All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package proto
-
-/*
- * Types and routines for supporting protocol buffer extensions.
- */
-
-import (
- "errors"
- "fmt"
- "reflect"
- "strconv"
- "sync"
-)
-
-// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message.
-var ErrMissingExtension = errors.New("proto: missing extension")
-
-// ExtensionRange represents a range of message extensions for a protocol buffer.
-// Used in code generated by the protocol compiler.
-type ExtensionRange struct {
- Start, End int32 // both inclusive
-}
-
-// extendableProto is an interface implemented by any protocol buffer that may be extended.
-type extendableProto interface {
- Message
- ExtensionRangeArray() []ExtensionRange
- ExtensionMap() map[int32]Extension
-}
-
-var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem()
-
-// ExtensionDesc represents an extension specification.
-// Used in generated code from the protocol compiler.
-type ExtensionDesc struct {
- ExtendedType Message // nil pointer to the type that is being extended
- ExtensionType interface{} // nil pointer to the extension type
- Field int32 // field number
- Name string // fully-qualified name of extension, for text formatting
- Tag string // protobuf tag style
-}
-
-func (ed *ExtensionDesc) repeated() bool {
- t := reflect.TypeOf(ed.ExtensionType)
- return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
-}
-
-// Extension represents an extension in a message.
-type Extension struct {
- // When an extension is stored in a message using SetExtension
- // only desc and value are set. When the message is marshaled
- // enc will be set to the encoded form of the message.
- //
- // When a message is unmarshaled and contains extensions, each
- // extension will have only enc set. When such an extension is
- // accessed using GetExtension (or GetExtensions) desc and value
- // will be set.
- desc *ExtensionDesc
- value interface{}
- enc []byte
-}
-
-// SetRawExtension is for testing only.
-func SetRawExtension(base extendableProto, id int32, b []byte) {
- base.ExtensionMap()[id] = Extension{enc: b}
-}
-
-// isExtensionField returns true iff the given field number is in an extension range.
-func isExtensionField(pb extendableProto, field int32) bool {
- for _, er := range pb.ExtensionRangeArray() {
- if er.Start <= field && field <= er.End {
- return true
- }
- }
- return false
-}
-
-// checkExtensionTypes checks that the given extension is valid for pb.
-func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
- // Check the extended type.
- if a, b := reflect.TypeOf(pb), reflect.TypeOf(extension.ExtendedType); a != b {
- return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String())
- }
- // Check the range.
- if !isExtensionField(pb, extension.Field) {
- return errors.New("proto: bad extension number; not in declared ranges")
- }
- return nil
-}
-
-// extPropKey is sufficient to uniquely identify an extension.
-type extPropKey struct {
- base reflect.Type
- field int32
-}
-
-var extProp = struct {
- sync.RWMutex
- m map[extPropKey]*Properties
-}{
- m: make(map[extPropKey]*Properties),
-}
-
-func extensionProperties(ed *ExtensionDesc) *Properties {
- key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field}
-
- extProp.RLock()
- if prop, ok := extProp.m[key]; ok {
- extProp.RUnlock()
- return prop
- }
- extProp.RUnlock()
-
- extProp.Lock()
- defer extProp.Unlock()
- // Check again.
- if prop, ok := extProp.m[key]; ok {
- return prop
- }
-
- prop := new(Properties)
- prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil)
- extProp.m[key] = prop
- return prop
-}
-
-// encodeExtensionMap encodes any unmarshaled (unencoded) extensions in m.
-func encodeExtensionMap(m map[int32]Extension) error {
- for k, e := range m {
- if e.value == nil || e.desc == nil {
- // Extension is only in its encoded form.
- continue
- }
-
- // We don't skip extensions that have an encoded form set,
- // because the extension value may have been mutated after
- // the last time this function was called.
-
- et := reflect.TypeOf(e.desc.ExtensionType)
- props := extensionProperties(e.desc)
-
- p := NewBuffer(nil)
- // If e.value has type T, the encoder expects a *struct{ X T }.
- // Pass a *T with a zero field and hope it all works out.
- x := reflect.New(et)
- x.Elem().Set(reflect.ValueOf(e.value))
- if err := props.enc(p, props, toStructPointer(x)); err != nil {
- return err
- }
- e.enc = p.buf
- m[k] = e
- }
- return nil
-}
-
-func sizeExtensionMap(m map[int32]Extension) (n int) {
- for _, e := range m {
- if e.value == nil || e.desc == nil {
- // Extension is only in its encoded form.
- n += len(e.enc)
- continue
- }
-
- // We don't skip extensions that have an encoded form set,
- // because the extension value may have been mutated after
- // the last time this function was called.
-
- et := reflect.TypeOf(e.desc.ExtensionType)
- props := extensionProperties(e.desc)
-
- // If e.value has type T, the encoder expects a *struct{ X T }.
- // Pass a *T with a zero field and hope it all works out.
- x := reflect.New(et)
- x.Elem().Set(reflect.ValueOf(e.value))
- n += props.size(props, toStructPointer(x))
- }
- return
-}
-
-// HasExtension returns whether the given extension is present in pb.
-func HasExtension(pb extendableProto, extension *ExtensionDesc) bool {
- // TODO: Check types, field numbers, etc.?
- _, ok := pb.ExtensionMap()[extension.Field]
- return ok
-}
-
-// ClearExtension removes the given extension from pb.
-func ClearExtension(pb extendableProto, extension *ExtensionDesc) {
- // TODO: Check types, field numbers, etc.?
- delete(pb.ExtensionMap(), extension.Field)
-}
-
-// GetExtension parses and returns the given extension of pb.
-// If the extension is not present it returns ErrMissingExtension.
-func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) {
- if err := checkExtensionTypes(pb, extension); err != nil {
- return nil, err
- }
-
- emap := pb.ExtensionMap()
- e, ok := emap[extension.Field]
- if !ok {
- return nil, ErrMissingExtension
- }
- if e.value != nil {
- // Already decoded. Check the descriptor, though.
- if e.desc != extension {
- // This shouldn't happen. If it does, it means that
- // GetExtension was called twice with two different
- // descriptors with the same field number.
- return nil, errors.New("proto: descriptor conflict")
- }
- return e.value, nil
- }
-
- v, err := decodeExtension(e.enc, extension)
- if err != nil {
- return nil, err
- }
-
- // Remember the decoded version and drop the encoded version.
- // That way it is safe to mutate what we return.
- e.value = v
- e.desc = extension
- e.enc = nil
- emap[extension.Field] = e
- return e.value, nil
-}
-
-// decodeExtension decodes an extension encoded in b.
-func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
- o := NewBuffer(b)
-
- t := reflect.TypeOf(extension.ExtensionType)
- rep := extension.repeated()
-
- props := extensionProperties(extension)
-
- // t is a pointer to a struct, pointer to basic type or a slice.
- // Allocate a "field" to store the pointer/slice itself; the
- // pointer/slice will be stored here. We pass
- // the address of this field to props.dec.
- // This passes a zero field and a *t and lets props.dec
- // interpret it as a *struct{ x t }.
- value := reflect.New(t).Elem()
-
- for {
- // Discard wire type and field number varint. It isn't needed.
- if _, err := o.DecodeVarint(); err != nil {
- return nil, err
- }
-
- if err := props.dec(o, props, toStructPointer(value.Addr())); err != nil {
- return nil, err
- }
-
- if !rep || o.index >= len(o.buf) {
- break
- }
- }
- return value.Interface(), nil
-}
-
-// GetExtensions returns a slice of the extensions present in pb that are also listed in es.
-// The returned slice has the same length as es; missing extensions will appear as nil elements.
-func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
- epb, ok := pb.(extendableProto)
- if !ok {
- err = errors.New("proto: not an extendable proto")
- return
- }
- extensions = make([]interface{}, len(es))
- for i, e := range es {
- extensions[i], err = GetExtension(epb, e)
- if err == ErrMissingExtension {
- err = nil
- }
- if err != nil {
- return
- }
- }
- return
-}
-
-// SetExtension sets the specified extension of pb to the specified value.
-func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{}) error {
- if err := checkExtensionTypes(pb, extension); err != nil {
- return err
- }
- typ := reflect.TypeOf(extension.ExtensionType)
- if typ != reflect.TypeOf(value) {
- return errors.New("proto: bad extension value type")
- }
- // nil extension values need to be caught early, because the
- // encoder can't distinguish an ErrNil due to a nil extension
- // from an ErrNil due to a missing field. Extensions are
- // always optional, so the encoder would just swallow the error
- // and drop all the extensions from the encoded message.
- if reflect.ValueOf(value).IsNil() {
- return fmt.Errorf("proto: SetExtension called with nil value of type %T", value)
- }
-
- pb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value}
- return nil
-}
-
-// A global registry of extensions.
-// The generated code will register the generated descriptors by calling RegisterExtension.
-
-var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc)
-
-// RegisterExtension is called from the generated code.
-func RegisterExtension(desc *ExtensionDesc) {
- st := reflect.TypeOf(desc.ExtendedType).Elem()
- m := extensionMaps[st]
- if m == nil {
- m = make(map[int32]*ExtensionDesc)
- extensionMaps[st] = m
- }
- if _, ok := m[desc.Field]; ok {
- panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field)))
- }
- m[desc.Field] = desc
-}
-
-// RegisteredExtensions returns a map of the registered extensions of a
-// protocol buffer struct, indexed by the extension number.
-// The argument pb should be a nil pointer to the struct type.
-func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
- return extensionMaps[reflect.TypeOf(pb).Elem()]
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/lib.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/lib.go
deleted file mode 100644
index f81052f2..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/lib.go
+++ /dev/null
@@ -1,759 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2010 The Go Authors. All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-/*
- Package proto converts data structures to and from the wire format of
- protocol buffers. It works in concert with the Go source code generated
- for .proto files by the protocol compiler.
-
- A summary of the properties of the protocol buffer interface
- for a protocol buffer variable v:
-
- - Names are turned from camel_case to CamelCase for export.
- - There are no methods on v to set fields; just treat
- them as structure fields.
- - There are getters that return a field's value if set,
- and return the field's default value if unset.
- The getters work even if the receiver is a nil message.
- - The zero value for a struct is its correct initialization state.
- All desired fields must be set before marshaling.
- - A Reset() method will restore a protobuf struct to its zero state.
- - Non-repeated fields are pointers to the values; nil means unset.
- That is, optional or required field int32 f becomes F *int32.
- - Repeated fields are slices.
- - Helper functions are available to aid the setting of fields.
- msg.Foo = proto.String("hello") // set field
- - Constants are defined to hold the default values of all fields that
- have them. They have the form Default_StructName_FieldName.
- Because the getter methods handle defaulted values,
- direct use of these constants should be rare.
- - Enums are given type names and maps from names to values.
- Enum values are prefixed by the enclosing message's name, or by the
- enum's type name if it is a top-level enum. Enum types have a String
- method, and a Enum method to assist in message construction.
- - Nested messages, groups and enums have type names prefixed with the name of
- the surrounding message type.
- - Extensions are given descriptor names that start with E_,
- followed by an underscore-delimited list of the nested messages
- that contain it (if any) followed by the CamelCased name of the
- extension field itself. HasExtension, ClearExtension, GetExtension
- and SetExtension are functions for manipulating extensions.
- - Marshal and Unmarshal are functions to encode and decode the wire format.
-
- The simplest way to describe this is to see an example.
- Given file test.proto, containing
-
- package example;
-
- enum FOO { X = 17; }
-
- message Test {
- required string label = 1;
- optional int32 type = 2 [default=77];
- repeated int64 reps = 3;
- optional group OptionalGroup = 4 {
- required string RequiredField = 5;
- }
- }
-
- The resulting file, test.pb.go, is:
-
- package example
-
- import proto "github.com/golang/protobuf/proto"
- import math "math"
-
- type FOO int32
- const (
- FOO_X FOO = 17
- )
- var FOO_name = map[int32]string{
- 17: "X",
- }
- var FOO_value = map[string]int32{
- "X": 17,
- }
-
- func (x FOO) Enum() *FOO {
- p := new(FOO)
- *p = x
- return p
- }
- func (x FOO) String() string {
- return proto.EnumName(FOO_name, int32(x))
- }
- func (x *FOO) UnmarshalJSON(data []byte) error {
- value, err := proto.UnmarshalJSONEnum(FOO_value, data)
- if err != nil {
- return err
- }
- *x = FOO(value)
- return nil
- }
-
- type Test struct {
- Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
- Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"`
- Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"`
- Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
- XXX_unrecognized []byte `json:"-"`
- }
- func (m *Test) Reset() { *m = Test{} }
- func (m *Test) String() string { return proto.CompactTextString(m) }
- func (*Test) ProtoMessage() {}
- const Default_Test_Type int32 = 77
-
- func (m *Test) GetLabel() string {
- if m != nil && m.Label != nil {
- return *m.Label
- }
- return ""
- }
-
- func (m *Test) GetType() int32 {
- if m != nil && m.Type != nil {
- return *m.Type
- }
- return Default_Test_Type
- }
-
- func (m *Test) GetOptionalgroup() *Test_OptionalGroup {
- if m != nil {
- return m.Optionalgroup
- }
- return nil
- }
-
- type Test_OptionalGroup struct {
- RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
- }
- func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} }
- func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
-
- func (m *Test_OptionalGroup) GetRequiredField() string {
- if m != nil && m.RequiredField != nil {
- return *m.RequiredField
- }
- return ""
- }
-
- func init() {
- proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
- }
-
- To create and play with a Test object:
-
- package main
-
- import (
- "log"
-
- "github.com/golang/protobuf/proto"
- pb "./example.pb"
- )
-
- func main() {
- test := &pb.Test{
- Label: proto.String("hello"),
- Type: proto.Int32(17),
- Optionalgroup: &pb.Test_OptionalGroup{
- RequiredField: proto.String("good bye"),
- },
- }
- data, err := proto.Marshal(test)
- if err != nil {
- log.Fatal("marshaling error: ", err)
- }
- newTest := &pb.Test{}
- err = proto.Unmarshal(data, newTest)
- if err != nil {
- log.Fatal("unmarshaling error: ", err)
- }
- // Now test and newTest contain the same data.
- if test.GetLabel() != newTest.GetLabel() {
- log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
- }
- // etc.
- }
-*/
-package proto
-
-import (
- "encoding/json"
- "fmt"
- "log"
- "reflect"
- "strconv"
- "sync"
-)
-
-// Message is implemented by generated protocol buffer messages.
-type Message interface {
- Reset()
- String() string
- ProtoMessage()
-}
-
-// Stats records allocation details about the protocol buffer encoders
-// and decoders. Useful for tuning the library itself.
-type Stats struct {
- Emalloc uint64 // mallocs in encode
- Dmalloc uint64 // mallocs in decode
- Encode uint64 // number of encodes
- Decode uint64 // number of decodes
- Chit uint64 // number of cache hits
- Cmiss uint64 // number of cache misses
- Size uint64 // number of sizes
-}
-
-// Set to true to enable stats collection.
-const collectStats = false
-
-var stats Stats
-
-// GetStats returns a copy of the global Stats structure.
-func GetStats() Stats { return stats }
-
-// A Buffer is a buffer manager for marshaling and unmarshaling
-// protocol buffers. It may be reused between invocations to
-// reduce memory usage. It is not necessary to use a Buffer;
-// the global functions Marshal and Unmarshal create a
-// temporary Buffer and are fine for most applications.
-type Buffer struct {
- buf []byte // encode/decode byte stream
- index int // write point
-
- // pools of basic types to amortize allocation.
- bools []bool
- uint32s []uint32
- uint64s []uint64
-
- // extra pools, only used with pointer_reflect.go
- int32s []int32
- int64s []int64
- float32s []float32
- float64s []float64
-}
-
-// NewBuffer allocates a new Buffer and initializes its internal data to
-// the contents of the argument slice.
-func NewBuffer(e []byte) *Buffer {
- return &Buffer{buf: e}
-}
-
-// Reset resets the Buffer, ready for marshaling a new protocol buffer.
-func (p *Buffer) Reset() {
- p.buf = p.buf[0:0] // for reading/writing
- p.index = 0 // for reading
-}
-
-// SetBuf replaces the internal buffer with the slice,
-// ready for unmarshaling the contents of the slice.
-func (p *Buffer) SetBuf(s []byte) {
- p.buf = s
- p.index = 0
-}
-
-// Bytes returns the contents of the Buffer.
-func (p *Buffer) Bytes() []byte { return p.buf }
-
-/*
- * Helper routines for simplifying the creation of optional fields of basic type.
- */
-
-// Bool is a helper routine that allocates a new bool value
-// to store v and returns a pointer to it.
-func Bool(v bool) *bool {
- return &v
-}
-
-// Int32 is a helper routine that allocates a new int32 value
-// to store v and returns a pointer to it.
-func Int32(v int32) *int32 {
- return &v
-}
-
-// Int is a helper routine that allocates a new int32 value
-// to store v and returns a pointer to it, but unlike Int32
-// its argument value is an int.
-func Int(v int) *int32 {
- p := new(int32)
- *p = int32(v)
- return p
-}
-
-// Int64 is a helper routine that allocates a new int64 value
-// to store v and returns a pointer to it.
-func Int64(v int64) *int64 {
- return &v
-}
-
-// Float32 is a helper routine that allocates a new float32 value
-// to store v and returns a pointer to it.
-func Float32(v float32) *float32 {
- return &v
-}
-
-// Float64 is a helper routine that allocates a new float64 value
-// to store v and returns a pointer to it.
-func Float64(v float64) *float64 {
- return &v
-}
-
-// Uint32 is a helper routine that allocates a new uint32 value
-// to store v and returns a pointer to it.
-func Uint32(v uint32) *uint32 {
- return &v
-}
-
-// Uint64 is a helper routine that allocates a new uint64 value
-// to store v and returns a pointer to it.
-func Uint64(v uint64) *uint64 {
- return &v
-}
-
-// String is a helper routine that allocates a new string value
-// to store v and returns a pointer to it.
-func String(v string) *string {
- return &v
-}
-
-// EnumName is a helper function to simplify printing protocol buffer enums
-// by name. Given an enum map and a value, it returns a useful string.
-func EnumName(m map[int32]string, v int32) string {
- s, ok := m[v]
- if ok {
- return s
- }
- return strconv.Itoa(int(v))
-}
-
-// UnmarshalJSONEnum is a helper function to simplify recovering enum int values
-// from their JSON-encoded representation. Given a map from the enum's symbolic
-// names to its int values, and a byte buffer containing the JSON-encoded
-// value, it returns an int32 that can be cast to the enum type by the caller.
-//
-// The function can deal with both JSON representations, numeric and symbolic.
-func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) {
- if data[0] == '"' {
- // New style: enums are strings.
- var repr string
- if err := json.Unmarshal(data, &repr); err != nil {
- return -1, err
- }
- val, ok := m[repr]
- if !ok {
- return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr)
- }
- return val, nil
- }
- // Old style: enums are ints.
- var val int32
- if err := json.Unmarshal(data, &val); err != nil {
- return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName)
- }
- return val, nil
-}
-
-// DebugPrint dumps the encoded data in b in a debugging format with a header
-// including the string s. Used in testing but made available for general debugging.
-func (o *Buffer) DebugPrint(s string, b []byte) {
- var u uint64
-
- obuf := o.buf
- index := o.index
- o.buf = b
- o.index = 0
- depth := 0
-
- fmt.Printf("\n--- %s ---\n", s)
-
-out:
- for {
- for i := 0; i < depth; i++ {
- fmt.Print(" ")
- }
-
- index := o.index
- if index == len(o.buf) {
- break
- }
-
- op, err := o.DecodeVarint()
- if err != nil {
- fmt.Printf("%3d: fetching op err %v\n", index, err)
- break out
- }
- tag := op >> 3
- wire := op & 7
-
- switch wire {
- default:
- fmt.Printf("%3d: t=%3d unknown wire=%d\n",
- index, tag, wire)
- break out
-
- case WireBytes:
- var r []byte
-
- r, err = o.DecodeRawBytes(false)
- if err != nil {
- break out
- }
- fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r))
- if len(r) <= 6 {
- for i := 0; i < len(r); i++ {
- fmt.Printf(" %.2x", r[i])
- }
- } else {
- for i := 0; i < 3; i++ {
- fmt.Printf(" %.2x", r[i])
- }
- fmt.Printf(" ..")
- for i := len(r) - 3; i < len(r); i++ {
- fmt.Printf(" %.2x", r[i])
- }
- }
- fmt.Printf("\n")
-
- case WireFixed32:
- u, err = o.DecodeFixed32()
- if err != nil {
- fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
- break out
- }
- fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
-
- case WireFixed64:
- u, err = o.DecodeFixed64()
- if err != nil {
- fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
- break out
- }
- fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
- break
-
- case WireVarint:
- u, err = o.DecodeVarint()
- if err != nil {
- fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
- break out
- }
- fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
-
- case WireStartGroup:
- if err != nil {
- fmt.Printf("%3d: t=%3d start err %v\n", index, tag, err)
- break out
- }
- fmt.Printf("%3d: t=%3d start\n", index, tag)
- depth++
-
- case WireEndGroup:
- depth--
- if err != nil {
- fmt.Printf("%3d: t=%3d end err %v\n", index, tag, err)
- break out
- }
- fmt.Printf("%3d: t=%3d end\n", index, tag)
- }
- }
-
- if depth != 0 {
- fmt.Printf("%3d: start-end not balanced %d\n", o.index, depth)
- }
- fmt.Printf("\n")
-
- o.buf = obuf
- o.index = index
-}
-
-// SetDefaults sets unset protocol buffer fields to their default values.
-// It only modifies fields that are both unset and have defined defaults.
-// It recursively sets default values in any non-nil sub-messages.
-func SetDefaults(pb Message) {
- setDefaults(reflect.ValueOf(pb), true, false)
-}
-
-// v is a pointer to a struct.
-func setDefaults(v reflect.Value, recur, zeros bool) {
- v = v.Elem()
-
- defaultMu.RLock()
- dm, ok := defaults[v.Type()]
- defaultMu.RUnlock()
- if !ok {
- dm = buildDefaultMessage(v.Type())
- defaultMu.Lock()
- defaults[v.Type()] = dm
- defaultMu.Unlock()
- }
-
- for _, sf := range dm.scalars {
- f := v.Field(sf.index)
- if !f.IsNil() {
- // field already set
- continue
- }
- dv := sf.value
- if dv == nil && !zeros {
- // no explicit default, and don't want to set zeros
- continue
- }
- fptr := f.Addr().Interface() // **T
- // TODO: Consider batching the allocations we do here.
- switch sf.kind {
- case reflect.Bool:
- b := new(bool)
- if dv != nil {
- *b = dv.(bool)
- }
- *(fptr.(**bool)) = b
- case reflect.Float32:
- f := new(float32)
- if dv != nil {
- *f = dv.(float32)
- }
- *(fptr.(**float32)) = f
- case reflect.Float64:
- f := new(float64)
- if dv != nil {
- *f = dv.(float64)
- }
- *(fptr.(**float64)) = f
- case reflect.Int32:
- // might be an enum
- if ft := f.Type(); ft != int32PtrType {
- // enum
- f.Set(reflect.New(ft.Elem()))
- if dv != nil {
- f.Elem().SetInt(int64(dv.(int32)))
- }
- } else {
- // int32 field
- i := new(int32)
- if dv != nil {
- *i = dv.(int32)
- }
- *(fptr.(**int32)) = i
- }
- case reflect.Int64:
- i := new(int64)
- if dv != nil {
- *i = dv.(int64)
- }
- *(fptr.(**int64)) = i
- case reflect.String:
- s := new(string)
- if dv != nil {
- *s = dv.(string)
- }
- *(fptr.(**string)) = s
- case reflect.Uint8:
- // exceptional case: []byte
- var b []byte
- if dv != nil {
- db := dv.([]byte)
- b = make([]byte, len(db))
- copy(b, db)
- } else {
- b = []byte{}
- }
- *(fptr.(*[]byte)) = b
- case reflect.Uint32:
- u := new(uint32)
- if dv != nil {
- *u = dv.(uint32)
- }
- *(fptr.(**uint32)) = u
- case reflect.Uint64:
- u := new(uint64)
- if dv != nil {
- *u = dv.(uint64)
- }
- *(fptr.(**uint64)) = u
- default:
- log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind)
- }
- }
-
- for _, ni := range dm.nested {
- f := v.Field(ni)
- if f.IsNil() {
- continue
- }
- // f is *T or []*T
- if f.Kind() == reflect.Ptr {
- setDefaults(f, recur, zeros)
- } else {
- for i := 0; i < f.Len(); i++ {
- e := f.Index(i)
- if e.IsNil() {
- continue
- }
- setDefaults(e, recur, zeros)
- }
- }
- }
-}
-
-var (
- // defaults maps a protocol buffer struct type to a slice of the fields,
- // with its scalar fields set to their proto-declared non-zero default values.
- defaultMu sync.RWMutex
- defaults = make(map[reflect.Type]defaultMessage)
-
- int32PtrType = reflect.TypeOf((*int32)(nil))
-)
-
-// defaultMessage represents information about the default values of a message.
-type defaultMessage struct {
- scalars []scalarField
- nested []int // struct field index of nested messages
-}
-
-type scalarField struct {
- index int // struct field index
- kind reflect.Kind // element type (the T in *T or []T)
- value interface{} // the proto-declared default value, or nil
-}
-
-func ptrToStruct(t reflect.Type) bool {
- return t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct
-}
-
-// t is a struct type.
-func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
- sprop := GetProperties(t)
- for _, prop := range sprop.Prop {
- fi, ok := sprop.decoderTags.get(prop.Tag)
- if !ok {
- // XXX_unrecognized
- continue
- }
- ft := t.Field(fi).Type
-
- // nested messages
- if ptrToStruct(ft) || (ft.Kind() == reflect.Slice && ptrToStruct(ft.Elem())) {
- dm.nested = append(dm.nested, fi)
- continue
- }
-
- sf := scalarField{
- index: fi,
- kind: ft.Elem().Kind(),
- }
-
- // scalar fields without defaults
- if !prop.HasDefault {
- dm.scalars = append(dm.scalars, sf)
- continue
- }
-
- // a scalar field: either *T or []byte
- switch ft.Elem().Kind() {
- case reflect.Bool:
- x, err := strconv.ParseBool(prop.Default)
- if err != nil {
- log.Printf("proto: bad default bool %q: %v", prop.Default, err)
- continue
- }
- sf.value = x
- case reflect.Float32:
- x, err := strconv.ParseFloat(prop.Default, 32)
- if err != nil {
- log.Printf("proto: bad default float32 %q: %v", prop.Default, err)
- continue
- }
- sf.value = float32(x)
- case reflect.Float64:
- x, err := strconv.ParseFloat(prop.Default, 64)
- if err != nil {
- log.Printf("proto: bad default float64 %q: %v", prop.Default, err)
- continue
- }
- sf.value = x
- case reflect.Int32:
- x, err := strconv.ParseInt(prop.Default, 10, 32)
- if err != nil {
- log.Printf("proto: bad default int32 %q: %v", prop.Default, err)
- continue
- }
- sf.value = int32(x)
- case reflect.Int64:
- x, err := strconv.ParseInt(prop.Default, 10, 64)
- if err != nil {
- log.Printf("proto: bad default int64 %q: %v", prop.Default, err)
- continue
- }
- sf.value = x
- case reflect.String:
- sf.value = prop.Default
- case reflect.Uint8:
- // []byte (not *uint8)
- sf.value = []byte(prop.Default)
- case reflect.Uint32:
- x, err := strconv.ParseUint(prop.Default, 10, 32)
- if err != nil {
- log.Printf("proto: bad default uint32 %q: %v", prop.Default, err)
- continue
- }
- sf.value = uint32(x)
- case reflect.Uint64:
- x, err := strconv.ParseUint(prop.Default, 10, 64)
- if err != nil {
- log.Printf("proto: bad default uint64 %q: %v", prop.Default, err)
- continue
- }
- sf.value = x
- default:
- log.Printf("proto: unhandled def kind %v", ft.Elem().Kind())
- continue
- }
-
- dm.scalars = append(dm.scalars, sf)
- }
-
- return dm
-}
-
-// Map fields may have key types of non-float scalars, strings and enums.
-// The easiest way to sort them in some deterministic order is to use fmt.
-// If this turns out to be inefficient we can always consider other options,
-// such as doing a Schwartzian transform.
-
-type mapKeys []reflect.Value
-
-func (s mapKeys) Len() int { return len(s) }
-func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
-func (s mapKeys) Less(i, j int) bool {
- return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface())
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/message_set.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/message_set.go
deleted file mode 100644
index 9d912bce..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/message_set.go
+++ /dev/null
@@ -1,287 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2010 The Go Authors. All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package proto
-
-/*
- * Support for message sets.
- */
-
-import (
- "bytes"
- "encoding/json"
- "errors"
- "fmt"
- "reflect"
- "sort"
-)
-
-// ErrNoMessageTypeId occurs when a protocol buffer does not have a message type ID.
-// A message type ID is required for storing a protocol buffer in a message set.
-var ErrNoMessageTypeId = errors.New("proto does not have a message type ID")
-
-// The first two types (_MessageSet_Item and MessageSet)
-// model what the protocol compiler produces for the following protocol message:
-// message MessageSet {
-// repeated group Item = 1 {
-// required int32 type_id = 2;
-// required string message = 3;
-// };
-// }
-// That is the MessageSet wire format. We can't use a proto to generate these
-// because that would introduce a circular dependency between it and this package.
-//
-// When a proto1 proto has a field that looks like:
-// optional message info = 3;
-// the protocol compiler produces a field in the generated struct that looks like:
-// Info *_proto_.MessageSet `protobuf:"bytes,3,opt,name=info"`
-// The package is automatically inserted so there is no need for that proto file to
-// import this package.
-
-type _MessageSet_Item struct {
- TypeId *int32 `protobuf:"varint,2,req,name=type_id"`
- Message []byte `protobuf:"bytes,3,req,name=message"`
-}
-
-type MessageSet struct {
- Item []*_MessageSet_Item `protobuf:"group,1,rep"`
- XXX_unrecognized []byte
- // TODO: caching?
-}
-
-// Make sure MessageSet is a Message.
-var _ Message = (*MessageSet)(nil)
-
-// messageTypeIder is an interface satisfied by a protocol buffer type
-// that may be stored in a MessageSet.
-type messageTypeIder interface {
- MessageTypeId() int32
-}
-
-func (ms *MessageSet) find(pb Message) *_MessageSet_Item {
- mti, ok := pb.(messageTypeIder)
- if !ok {
- return nil
- }
- id := mti.MessageTypeId()
- for _, item := range ms.Item {
- if *item.TypeId == id {
- return item
- }
- }
- return nil
-}
-
-func (ms *MessageSet) Has(pb Message) bool {
- if ms.find(pb) != nil {
- return true
- }
- return false
-}
-
-func (ms *MessageSet) Unmarshal(pb Message) error {
- if item := ms.find(pb); item != nil {
- return Unmarshal(item.Message, pb)
- }
- if _, ok := pb.(messageTypeIder); !ok {
- return ErrNoMessageTypeId
- }
- return nil // TODO: return error instead?
-}
-
-func (ms *MessageSet) Marshal(pb Message) error {
- msg, err := Marshal(pb)
- if err != nil {
- return err
- }
- if item := ms.find(pb); item != nil {
- // reuse existing item
- item.Message = msg
- return nil
- }
-
- mti, ok := pb.(messageTypeIder)
- if !ok {
- return ErrNoMessageTypeId
- }
-
- mtid := mti.MessageTypeId()
- ms.Item = append(ms.Item, &_MessageSet_Item{
- TypeId: &mtid,
- Message: msg,
- })
- return nil
-}
-
-func (ms *MessageSet) Reset() { *ms = MessageSet{} }
-func (ms *MessageSet) String() string { return CompactTextString(ms) }
-func (*MessageSet) ProtoMessage() {}
-
-// Support for the message_set_wire_format message option.
-
-func skipVarint(buf []byte) []byte {
- i := 0
- for ; buf[i]&0x80 != 0; i++ {
- }
- return buf[i+1:]
-}
-
-// MarshalMessageSet encodes the extension map represented by m in the message set wire format.
-// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
-func MarshalMessageSet(m map[int32]Extension) ([]byte, error) {
- if err := encodeExtensionMap(m); err != nil {
- return nil, err
- }
-
- // Sort extension IDs to provide a deterministic encoding.
- // See also enc_map in encode.go.
- ids := make([]int, 0, len(m))
- for id := range m {
- ids = append(ids, int(id))
- }
- sort.Ints(ids)
-
- ms := &MessageSet{Item: make([]*_MessageSet_Item, 0, len(m))}
- for _, id := range ids {
- e := m[int32(id)]
- // Remove the wire type and field number varint, as well as the length varint.
- msg := skipVarint(skipVarint(e.enc))
-
- ms.Item = append(ms.Item, &_MessageSet_Item{
- TypeId: Int32(int32(id)),
- Message: msg,
- })
- }
- return Marshal(ms)
-}
-
-// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
-// It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
-func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error {
- ms := new(MessageSet)
- if err := Unmarshal(buf, ms); err != nil {
- return err
- }
- for _, item := range ms.Item {
- id := *item.TypeId
- msg := item.Message
-
- // Restore wire type and field number varint, plus length varint.
- // Be careful to preserve duplicate items.
- b := EncodeVarint(uint64(id)<<3 | WireBytes)
- if ext, ok := m[id]; ok {
- // Existing data; rip off the tag and length varint
- // so we join the new data correctly.
- // We can assume that ext.enc is set because we are unmarshaling.
- o := ext.enc[len(b):] // skip wire type and field number
- _, n := DecodeVarint(o) // calculate length of length varint
- o = o[n:] // skip length varint
- msg = append(o, msg...) // join old data and new data
- }
- b = append(b, EncodeVarint(uint64(len(msg)))...)
- b = append(b, msg...)
-
- m[id] = Extension{enc: b}
- }
- return nil
-}
-
-// MarshalMessageSetJSON encodes the extension map represented by m in JSON format.
-// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
-func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) {
- var b bytes.Buffer
- b.WriteByte('{')
-
- // Process the map in key order for deterministic output.
- ids := make([]int32, 0, len(m))
- for id := range m {
- ids = append(ids, id)
- }
- sort.Sort(int32Slice(ids)) // int32Slice defined in text.go
-
- for i, id := range ids {
- ext := m[id]
- if i > 0 {
- b.WriteByte(',')
- }
-
- msd, ok := messageSetMap[id]
- if !ok {
- // Unknown type; we can't render it, so skip it.
- continue
- }
- fmt.Fprintf(&b, `"[%s]":`, msd.name)
-
- x := ext.value
- if x == nil {
- x = reflect.New(msd.t.Elem()).Interface()
- if err := Unmarshal(ext.enc, x.(Message)); err != nil {
- return nil, err
- }
- }
- d, err := json.Marshal(x)
- if err != nil {
- return nil, err
- }
- b.Write(d)
- }
- b.WriteByte('}')
- return b.Bytes(), nil
-}
-
-// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format.
-// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
-func UnmarshalMessageSetJSON(buf []byte, m map[int32]Extension) error {
- // Common-case fast path.
- if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) {
- return nil
- }
-
- // This is fairly tricky, and it's not clear that it is needed.
- return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented")
-}
-
-// A global registry of types that can be used in a MessageSet.
-
-var messageSetMap = make(map[int32]messageSetDesc)
-
-type messageSetDesc struct {
- t reflect.Type // pointer to struct
- name string
-}
-
-// RegisterMessageSetType is called from the generated code.
-func RegisterMessageSetType(m Message, fieldNum int32, name string) {
- messageSetMap[fieldNum] = messageSetDesc{
- t: reflect.TypeOf(m),
- name: name,
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_reflect.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_reflect.go
deleted file mode 100644
index c68b1252..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_reflect.go
+++ /dev/null
@@ -1,479 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2012 The Go Authors. All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// +build appengine
-
-// This file contains an implementation of proto field accesses using package reflect.
-// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
-// be used on App Engine.
-
-package proto
-
-import (
- "math"
- "reflect"
-)
-
-// A structPointer is a pointer to a struct.
-type structPointer struct {
- v reflect.Value
-}
-
-// toStructPointer returns a structPointer equivalent to the given reflect value.
-// The reflect value must itself be a pointer to a struct.
-func toStructPointer(v reflect.Value) structPointer {
- return structPointer{v}
-}
-
-// IsNil reports whether p is nil.
-func structPointer_IsNil(p structPointer) bool {
- return p.v.IsNil()
-}
-
-// Interface returns the struct pointer as an interface value.
-func structPointer_Interface(p structPointer, _ reflect.Type) interface{} {
- return p.v.Interface()
-}
-
-// A field identifies a field in a struct, accessible from a structPointer.
-// In this implementation, a field is identified by the sequence of field indices
-// passed to reflect's FieldByIndex.
-type field []int
-
-// toField returns a field equivalent to the given reflect field.
-func toField(f *reflect.StructField) field {
- return f.Index
-}
-
-// invalidField is an invalid field identifier.
-var invalidField = field(nil)
-
-// IsValid reports whether the field identifier is valid.
-func (f field) IsValid() bool { return f != nil }
-
-// field returns the given field in the struct as a reflect value.
-func structPointer_field(p structPointer, f field) reflect.Value {
- // Special case: an extension map entry with a value of type T
- // passes a *T to the struct-handling code with a zero field,
- // expecting that it will be treated as equivalent to *struct{ X T },
- // which has the same memory layout. We have to handle that case
- // specially, because reflect will panic if we call FieldByIndex on a
- // non-struct.
- if f == nil {
- return p.v.Elem()
- }
-
- return p.v.Elem().FieldByIndex(f)
-}
-
-// ifield returns the given field in the struct as an interface value.
-func structPointer_ifield(p structPointer, f field) interface{} {
- return structPointer_field(p, f).Addr().Interface()
-}
-
-// Bytes returns the address of a []byte field in the struct.
-func structPointer_Bytes(p structPointer, f field) *[]byte {
- return structPointer_ifield(p, f).(*[]byte)
-}
-
-// BytesSlice returns the address of a [][]byte field in the struct.
-func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
- return structPointer_ifield(p, f).(*[][]byte)
-}
-
-// Bool returns the address of a *bool field in the struct.
-func structPointer_Bool(p structPointer, f field) **bool {
- return structPointer_ifield(p, f).(**bool)
-}
-
-// BoolVal returns the address of a bool field in the struct.
-func structPointer_BoolVal(p structPointer, f field) *bool {
- return structPointer_ifield(p, f).(*bool)
-}
-
-// BoolSlice returns the address of a []bool field in the struct.
-func structPointer_BoolSlice(p structPointer, f field) *[]bool {
- return structPointer_ifield(p, f).(*[]bool)
-}
-
-// String returns the address of a *string field in the struct.
-func structPointer_String(p structPointer, f field) **string {
- return structPointer_ifield(p, f).(**string)
-}
-
-// StringVal returns the address of a string field in the struct.
-func structPointer_StringVal(p structPointer, f field) *string {
- return structPointer_ifield(p, f).(*string)
-}
-
-// StringSlice returns the address of a []string field in the struct.
-func structPointer_StringSlice(p structPointer, f field) *[]string {
- return structPointer_ifield(p, f).(*[]string)
-}
-
-// ExtMap returns the address of an extension map field in the struct.
-func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
- return structPointer_ifield(p, f).(*map[int32]Extension)
-}
-
-// Map returns the reflect.Value for the address of a map field in the struct.
-func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value {
- return structPointer_field(p, f).Addr()
-}
-
-// SetStructPointer writes a *struct field in the struct.
-func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
- structPointer_field(p, f).Set(q.v)
-}
-
-// GetStructPointer reads a *struct field in the struct.
-func structPointer_GetStructPointer(p structPointer, f field) structPointer {
- return structPointer{structPointer_field(p, f)}
-}
-
-// StructPointerSlice the address of a []*struct field in the struct.
-func structPointer_StructPointerSlice(p structPointer, f field) structPointerSlice {
- return structPointerSlice{structPointer_field(p, f)}
-}
-
-// A structPointerSlice represents the address of a slice of pointers to structs
-// (themselves messages or groups). That is, v.Type() is *[]*struct{...}.
-type structPointerSlice struct {
- v reflect.Value
-}
-
-func (p structPointerSlice) Len() int { return p.v.Len() }
-func (p structPointerSlice) Index(i int) structPointer { return structPointer{p.v.Index(i)} }
-func (p structPointerSlice) Append(q structPointer) {
- p.v.Set(reflect.Append(p.v, q.v))
-}
-
-var (
- int32Type = reflect.TypeOf(int32(0))
- uint32Type = reflect.TypeOf(uint32(0))
- float32Type = reflect.TypeOf(float32(0))
- int64Type = reflect.TypeOf(int64(0))
- uint64Type = reflect.TypeOf(uint64(0))
- float64Type = reflect.TypeOf(float64(0))
-)
-
-// A word32 represents a field of type *int32, *uint32, *float32, or *enum.
-// That is, v.Type() is *int32, *uint32, *float32, or *enum and v is assignable.
-type word32 struct {
- v reflect.Value
-}
-
-// IsNil reports whether p is nil.
-func word32_IsNil(p word32) bool {
- return p.v.IsNil()
-}
-
-// Set sets p to point at a newly allocated word with bits set to x.
-func word32_Set(p word32, o *Buffer, x uint32) {
- t := p.v.Type().Elem()
- switch t {
- case int32Type:
- if len(o.int32s) == 0 {
- o.int32s = make([]int32, uint32PoolSize)
- }
- o.int32s[0] = int32(x)
- p.v.Set(reflect.ValueOf(&o.int32s[0]))
- o.int32s = o.int32s[1:]
- return
- case uint32Type:
- if len(o.uint32s) == 0 {
- o.uint32s = make([]uint32, uint32PoolSize)
- }
- o.uint32s[0] = x
- p.v.Set(reflect.ValueOf(&o.uint32s[0]))
- o.uint32s = o.uint32s[1:]
- return
- case float32Type:
- if len(o.float32s) == 0 {
- o.float32s = make([]float32, uint32PoolSize)
- }
- o.float32s[0] = math.Float32frombits(x)
- p.v.Set(reflect.ValueOf(&o.float32s[0]))
- o.float32s = o.float32s[1:]
- return
- }
-
- // must be enum
- p.v.Set(reflect.New(t))
- p.v.Elem().SetInt(int64(int32(x)))
-}
-
-// Get gets the bits pointed at by p, as a uint32.
-func word32_Get(p word32) uint32 {
- elem := p.v.Elem()
- switch elem.Kind() {
- case reflect.Int32:
- return uint32(elem.Int())
- case reflect.Uint32:
- return uint32(elem.Uint())
- case reflect.Float32:
- return math.Float32bits(float32(elem.Float()))
- }
- panic("unreachable")
-}
-
-// Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct.
-func structPointer_Word32(p structPointer, f field) word32 {
- return word32{structPointer_field(p, f)}
-}
-
-// A word32Val represents a field of type int32, uint32, float32, or enum.
-// That is, v.Type() is int32, uint32, float32, or enum and v is assignable.
-type word32Val struct {
- v reflect.Value
-}
-
-// Set sets *p to x.
-func word32Val_Set(p word32Val, x uint32) {
- switch p.v.Type() {
- case int32Type:
- p.v.SetInt(int64(x))
- return
- case uint32Type:
- p.v.SetUint(uint64(x))
- return
- case float32Type:
- p.v.SetFloat(float64(math.Float32frombits(x)))
- return
- }
-
- // must be enum
- p.v.SetInt(int64(int32(x)))
-}
-
-// Get gets the bits pointed at by p, as a uint32.
-func word32Val_Get(p word32Val) uint32 {
- elem := p.v
- switch elem.Kind() {
- case reflect.Int32:
- return uint32(elem.Int())
- case reflect.Uint32:
- return uint32(elem.Uint())
- case reflect.Float32:
- return math.Float32bits(float32(elem.Float()))
- }
- panic("unreachable")
-}
-
-// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct.
-func structPointer_Word32Val(p structPointer, f field) word32Val {
- return word32Val{structPointer_field(p, f)}
-}
-
-// A word32Slice is a slice of 32-bit values.
-// That is, v.Type() is []int32, []uint32, []float32, or []enum.
-type word32Slice struct {
- v reflect.Value
-}
-
-func (p word32Slice) Append(x uint32) {
- n, m := p.v.Len(), p.v.Cap()
- if n < m {
- p.v.SetLen(n + 1)
- } else {
- t := p.v.Type().Elem()
- p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
- }
- elem := p.v.Index(n)
- switch elem.Kind() {
- case reflect.Int32:
- elem.SetInt(int64(int32(x)))
- case reflect.Uint32:
- elem.SetUint(uint64(x))
- case reflect.Float32:
- elem.SetFloat(float64(math.Float32frombits(x)))
- }
-}
-
-func (p word32Slice) Len() int {
- return p.v.Len()
-}
-
-func (p word32Slice) Index(i int) uint32 {
- elem := p.v.Index(i)
- switch elem.Kind() {
- case reflect.Int32:
- return uint32(elem.Int())
- case reflect.Uint32:
- return uint32(elem.Uint())
- case reflect.Float32:
- return math.Float32bits(float32(elem.Float()))
- }
- panic("unreachable")
-}
-
-// Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct.
-func structPointer_Word32Slice(p structPointer, f field) word32Slice {
- return word32Slice{structPointer_field(p, f)}
-}
-
-// word64 is like word32 but for 64-bit values.
-type word64 struct {
- v reflect.Value
-}
-
-func word64_Set(p word64, o *Buffer, x uint64) {
- t := p.v.Type().Elem()
- switch t {
- case int64Type:
- if len(o.int64s) == 0 {
- o.int64s = make([]int64, uint64PoolSize)
- }
- o.int64s[0] = int64(x)
- p.v.Set(reflect.ValueOf(&o.int64s[0]))
- o.int64s = o.int64s[1:]
- return
- case uint64Type:
- if len(o.uint64s) == 0 {
- o.uint64s = make([]uint64, uint64PoolSize)
- }
- o.uint64s[0] = x
- p.v.Set(reflect.ValueOf(&o.uint64s[0]))
- o.uint64s = o.uint64s[1:]
- return
- case float64Type:
- if len(o.float64s) == 0 {
- o.float64s = make([]float64, uint64PoolSize)
- }
- o.float64s[0] = math.Float64frombits(x)
- p.v.Set(reflect.ValueOf(&o.float64s[0]))
- o.float64s = o.float64s[1:]
- return
- }
- panic("unreachable")
-}
-
-func word64_IsNil(p word64) bool {
- return p.v.IsNil()
-}
-
-func word64_Get(p word64) uint64 {
- elem := p.v.Elem()
- switch elem.Kind() {
- case reflect.Int64:
- return uint64(elem.Int())
- case reflect.Uint64:
- return elem.Uint()
- case reflect.Float64:
- return math.Float64bits(elem.Float())
- }
- panic("unreachable")
-}
-
-func structPointer_Word64(p structPointer, f field) word64 {
- return word64{structPointer_field(p, f)}
-}
-
-// word64Val is like word32Val but for 64-bit values.
-type word64Val struct {
- v reflect.Value
-}
-
-func word64Val_Set(p word64Val, o *Buffer, x uint64) {
- switch p.v.Type() {
- case int64Type:
- p.v.SetInt(int64(x))
- return
- case uint64Type:
- p.v.SetUint(x)
- return
- case float64Type:
- p.v.SetFloat(math.Float64frombits(x))
- return
- }
- panic("unreachable")
-}
-
-func word64Val_Get(p word64Val) uint64 {
- elem := p.v
- switch elem.Kind() {
- case reflect.Int64:
- return uint64(elem.Int())
- case reflect.Uint64:
- return elem.Uint()
- case reflect.Float64:
- return math.Float64bits(elem.Float())
- }
- panic("unreachable")
-}
-
-func structPointer_Word64Val(p structPointer, f field) word64Val {
- return word64Val{structPointer_field(p, f)}
-}
-
-type word64Slice struct {
- v reflect.Value
-}
-
-func (p word64Slice) Append(x uint64) {
- n, m := p.v.Len(), p.v.Cap()
- if n < m {
- p.v.SetLen(n + 1)
- } else {
- t := p.v.Type().Elem()
- p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
- }
- elem := p.v.Index(n)
- switch elem.Kind() {
- case reflect.Int64:
- elem.SetInt(int64(int64(x)))
- case reflect.Uint64:
- elem.SetUint(uint64(x))
- case reflect.Float64:
- elem.SetFloat(float64(math.Float64frombits(x)))
- }
-}
-
-func (p word64Slice) Len() int {
- return p.v.Len()
-}
-
-func (p word64Slice) Index(i int) uint64 {
- elem := p.v.Index(i)
- switch elem.Kind() {
- case reflect.Int64:
- return uint64(elem.Int())
- case reflect.Uint64:
- return uint64(elem.Uint())
- case reflect.Float64:
- return math.Float64bits(float64(elem.Float()))
- }
- panic("unreachable")
-}
-
-func structPointer_Word64Slice(p structPointer, f field) word64Slice {
- return word64Slice{structPointer_field(p, f)}
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_unsafe.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_unsafe.go
deleted file mode 100644
index 48bc0fa4..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_unsafe.go
+++ /dev/null
@@ -1,266 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2012 The Go Authors. All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// +build !appengine
-
-// This file contains the implementation of the proto field accesses using package unsafe.
-
-package proto
-
-import (
- "reflect"
- "unsafe"
-)
-
-// NOTE: These type_Foo functions would more idiomatically be methods,
-// but Go does not allow methods on pointer types, and we must preserve
-// some pointer type for the garbage collector. We use these
-// funcs with clunky names as our poor approximation to methods.
-//
-// An alternative would be
-// type structPointer struct { p unsafe.Pointer }
-// but that does not registerize as well.
-
-// A structPointer is a pointer to a struct.
-type structPointer unsafe.Pointer
-
-// toStructPointer returns a structPointer equivalent to the given reflect value.
-func toStructPointer(v reflect.Value) structPointer {
- return structPointer(unsafe.Pointer(v.Pointer()))
-}
-
-// IsNil reports whether p is nil.
-func structPointer_IsNil(p structPointer) bool {
- return p == nil
-}
-
-// Interface returns the struct pointer, assumed to have element type t,
-// as an interface value.
-func structPointer_Interface(p structPointer, t reflect.Type) interface{} {
- return reflect.NewAt(t, unsafe.Pointer(p)).Interface()
-}
-
-// A field identifies a field in a struct, accessible from a structPointer.
-// In this implementation, a field is identified by its byte offset from the start of the struct.
-type field uintptr
-
-// toField returns a field equivalent to the given reflect field.
-func toField(f *reflect.StructField) field {
- return field(f.Offset)
-}
-
-// invalidField is an invalid field identifier.
-const invalidField = ^field(0)
-
-// IsValid reports whether the field identifier is valid.
-func (f field) IsValid() bool {
- return f != ^field(0)
-}
-
-// Bytes returns the address of a []byte field in the struct.
-func structPointer_Bytes(p structPointer, f field) *[]byte {
- return (*[]byte)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// BytesSlice returns the address of a [][]byte field in the struct.
-func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
- return (*[][]byte)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// Bool returns the address of a *bool field in the struct.
-func structPointer_Bool(p structPointer, f field) **bool {
- return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// BoolVal returns the address of a bool field in the struct.
-func structPointer_BoolVal(p structPointer, f field) *bool {
- return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// BoolSlice returns the address of a []bool field in the struct.
-func structPointer_BoolSlice(p structPointer, f field) *[]bool {
- return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// String returns the address of a *string field in the struct.
-func structPointer_String(p structPointer, f field) **string {
- return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// StringVal returns the address of a string field in the struct.
-func structPointer_StringVal(p structPointer, f field) *string {
- return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// StringSlice returns the address of a []string field in the struct.
-func structPointer_StringSlice(p structPointer, f field) *[]string {
- return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// ExtMap returns the address of an extension map field in the struct.
-func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
- return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// Map returns the reflect.Value for the address of a map field in the struct.
-func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value {
- return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f)))
-}
-
-// SetStructPointer writes a *struct field in the struct.
-func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
- *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q
-}
-
-// GetStructPointer reads a *struct field in the struct.
-func structPointer_GetStructPointer(p structPointer, f field) structPointer {
- return *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// StructPointerSlice the address of a []*struct field in the struct.
-func structPointer_StructPointerSlice(p structPointer, f field) *structPointerSlice {
- return (*structPointerSlice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// A structPointerSlice represents a slice of pointers to structs (themselves submessages or groups).
-type structPointerSlice []structPointer
-
-func (v *structPointerSlice) Len() int { return len(*v) }
-func (v *structPointerSlice) Index(i int) structPointer { return (*v)[i] }
-func (v *structPointerSlice) Append(p structPointer) { *v = append(*v, p) }
-
-// A word32 is the address of a "pointer to 32-bit value" field.
-type word32 **uint32
-
-// IsNil reports whether *v is nil.
-func word32_IsNil(p word32) bool {
- return *p == nil
-}
-
-// Set sets *v to point at a newly allocated word set to x.
-func word32_Set(p word32, o *Buffer, x uint32) {
- if len(o.uint32s) == 0 {
- o.uint32s = make([]uint32, uint32PoolSize)
- }
- o.uint32s[0] = x
- *p = &o.uint32s[0]
- o.uint32s = o.uint32s[1:]
-}
-
-// Get gets the value pointed at by *v.
-func word32_Get(p word32) uint32 {
- return **p
-}
-
-// Word32 returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
-func structPointer_Word32(p structPointer, f field) word32 {
- return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
-}
-
-// A word32Val is the address of a 32-bit value field.
-type word32Val *uint32
-
-// Set sets *p to x.
-func word32Val_Set(p word32Val, x uint32) {
- *p = x
-}
-
-// Get gets the value pointed at by p.
-func word32Val_Get(p word32Val) uint32 {
- return *p
-}
-
-// Word32Val returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
-func structPointer_Word32Val(p structPointer, f field) word32Val {
- return word32Val((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
-}
-
-// A word32Slice is a slice of 32-bit values.
-type word32Slice []uint32
-
-func (v *word32Slice) Append(x uint32) { *v = append(*v, x) }
-func (v *word32Slice) Len() int { return len(*v) }
-func (v *word32Slice) Index(i int) uint32 { return (*v)[i] }
-
-// Word32Slice returns the address of a []int32, []uint32, []float32, or []enum field in the struct.
-func structPointer_Word32Slice(p structPointer, f field) *word32Slice {
- return (*word32Slice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// word64 is like word32 but for 64-bit values.
-type word64 **uint64
-
-func word64_Set(p word64, o *Buffer, x uint64) {
- if len(o.uint64s) == 0 {
- o.uint64s = make([]uint64, uint64PoolSize)
- }
- o.uint64s[0] = x
- *p = &o.uint64s[0]
- o.uint64s = o.uint64s[1:]
-}
-
-func word64_IsNil(p word64) bool {
- return *p == nil
-}
-
-func word64_Get(p word64) uint64 {
- return **p
-}
-
-func structPointer_Word64(p structPointer, f field) word64 {
- return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
-}
-
-// word64Val is like word32Val but for 64-bit values.
-type word64Val *uint64
-
-func word64Val_Set(p word64Val, o *Buffer, x uint64) {
- *p = x
-}
-
-func word64Val_Get(p word64Val) uint64 {
- return *p
-}
-
-func structPointer_Word64Val(p structPointer, f field) word64Val {
- return word64Val((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
-}
-
-// word64Slice is like word32Slice but for 64-bit values.
-type word64Slice []uint64
-
-func (v *word64Slice) Append(x uint64) { *v = append(*v, x) }
-func (v *word64Slice) Len() int { return len(*v) }
-func (v *word64Slice) Index(i int) uint64 { return (*v)[i] }
-
-func structPointer_Word64Slice(p structPointer, f field) *word64Slice {
- return (*word64Slice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/properties.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/properties.go
deleted file mode 100644
index 72165448..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/properties.go
+++ /dev/null
@@ -1,737 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2010 The Go Authors. All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package proto
-
-/*
- * Routines for encoding data into the wire format for protocol buffers.
- */
-
-import (
- "fmt"
- "os"
- "reflect"
- "sort"
- "strconv"
- "strings"
- "sync"
-)
-
-const debug bool = false
-
-// Constants that identify the encoding of a value on the wire.
-const (
- WireVarint = 0
- WireFixed64 = 1
- WireBytes = 2
- WireStartGroup = 3
- WireEndGroup = 4
- WireFixed32 = 5
-)
-
-const startSize = 10 // initial slice/string sizes
-
-// Encoders are defined in encode.go
-// An encoder outputs the full representation of a field, including its
-// tag and encoder type.
-type encoder func(p *Buffer, prop *Properties, base structPointer) error
-
-// A valueEncoder encodes a single integer in a particular encoding.
-type valueEncoder func(o *Buffer, x uint64) error
-
-// Sizers are defined in encode.go
-// A sizer returns the encoded size of a field, including its tag and encoder
-// type.
-type sizer func(prop *Properties, base structPointer) int
-
-// A valueSizer returns the encoded size of a single integer in a particular
-// encoding.
-type valueSizer func(x uint64) int
-
-// Decoders are defined in decode.go
-// A decoder creates a value from its wire representation.
-// Unrecognized subelements are saved in unrec.
-type decoder func(p *Buffer, prop *Properties, base structPointer) error
-
-// A valueDecoder decodes a single integer in a particular encoding.
-type valueDecoder func(o *Buffer) (x uint64, err error)
-
-// tagMap is an optimization over map[int]int for typical protocol buffer
-// use-cases. Encoded protocol buffers are often in tag order with small tag
-// numbers.
-type tagMap struct {
- fastTags []int
- slowTags map[int]int
-}
-
-// tagMapFastLimit is the upper bound on the tag number that will be stored in
-// the tagMap slice rather than its map.
-const tagMapFastLimit = 1024
-
-func (p *tagMap) get(t int) (int, bool) {
- if t > 0 && t < tagMapFastLimit {
- if t >= len(p.fastTags) {
- return 0, false
- }
- fi := p.fastTags[t]
- return fi, fi >= 0
- }
- fi, ok := p.slowTags[t]
- return fi, ok
-}
-
-func (p *tagMap) put(t int, fi int) {
- if t > 0 && t < tagMapFastLimit {
- for len(p.fastTags) < t+1 {
- p.fastTags = append(p.fastTags, -1)
- }
- p.fastTags[t] = fi
- return
- }
- if p.slowTags == nil {
- p.slowTags = make(map[int]int)
- }
- p.slowTags[t] = fi
-}
-
-// StructProperties represents properties for all the fields of a struct.
-// decoderTags and decoderOrigNames should only be used by the decoder.
-type StructProperties struct {
- Prop []*Properties // properties for each field
- reqCount int // required count
- decoderTags tagMap // map from proto tag to struct field number
- decoderOrigNames map[string]int // map from original name to struct field number
- order []int // list of struct field numbers in tag order
- unrecField field // field id of the XXX_unrecognized []byte field
- extendable bool // is this an extendable proto
-}
-
-// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
-// See encode.go, (*Buffer).enc_struct.
-
-func (sp *StructProperties) Len() int { return len(sp.order) }
-func (sp *StructProperties) Less(i, j int) bool {
- return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag
-}
-func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }
-
-// Properties represents the protocol-specific behavior of a single struct field.
-type Properties struct {
- Name string // name of the field, for error messages
- OrigName string // original name before protocol compiler (always set)
- Wire string
- WireType int
- Tag int
- Required bool
- Optional bool
- Repeated bool
- Packed bool // relevant for repeated primitives only
- Enum string // set for enum types only
- proto3 bool // whether this is known to be a proto3 field; set for []byte only
-
- Default string // default value
- HasDefault bool // whether an explicit default was provided
- def_uint64 uint64
-
- enc encoder
- valEnc valueEncoder // set for bool and numeric types only
- field field
- tagcode []byte // encoding of EncodeVarint((Tag<<3)|WireType)
- tagbuf [8]byte
- stype reflect.Type // set for struct types only
- sprop *StructProperties // set for struct types only
- isMarshaler bool
- isUnmarshaler bool
-
- mtype reflect.Type // set for map types only
- mkeyprop *Properties // set for map types only
- mvalprop *Properties // set for map types only
-
- size sizer
- valSize valueSizer // set for bool and numeric types only
-
- dec decoder
- valDec valueDecoder // set for bool and numeric types only
-
- // If this is a packable field, this will be the decoder for the packed version of the field.
- packedDec decoder
-}
-
-// String formats the properties in the protobuf struct field tag style.
-func (p *Properties) String() string {
- s := p.Wire
- s = ","
- s += strconv.Itoa(p.Tag)
- if p.Required {
- s += ",req"
- }
- if p.Optional {
- s += ",opt"
- }
- if p.Repeated {
- s += ",rep"
- }
- if p.Packed {
- s += ",packed"
- }
- if p.OrigName != p.Name {
- s += ",name=" + p.OrigName
- }
- if p.proto3 {
- s += ",proto3"
- }
- if len(p.Enum) > 0 {
- s += ",enum=" + p.Enum
- }
- if p.HasDefault {
- s += ",def=" + p.Default
- }
- return s
-}
-
-// Parse populates p by parsing a string in the protobuf struct field tag style.
-func (p *Properties) Parse(s string) {
- // "bytes,49,opt,name=foo,def=hello!"
- fields := strings.Split(s, ",") // breaks def=, but handled below.
- if len(fields) < 2 {
- fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
- return
- }
-
- p.Wire = fields[0]
- switch p.Wire {
- case "varint":
- p.WireType = WireVarint
- p.valEnc = (*Buffer).EncodeVarint
- p.valDec = (*Buffer).DecodeVarint
- p.valSize = sizeVarint
- case "fixed32":
- p.WireType = WireFixed32
- p.valEnc = (*Buffer).EncodeFixed32
- p.valDec = (*Buffer).DecodeFixed32
- p.valSize = sizeFixed32
- case "fixed64":
- p.WireType = WireFixed64
- p.valEnc = (*Buffer).EncodeFixed64
- p.valDec = (*Buffer).DecodeFixed64
- p.valSize = sizeFixed64
- case "zigzag32":
- p.WireType = WireVarint
- p.valEnc = (*Buffer).EncodeZigzag32
- p.valDec = (*Buffer).DecodeZigzag32
- p.valSize = sizeZigzag32
- case "zigzag64":
- p.WireType = WireVarint
- p.valEnc = (*Buffer).EncodeZigzag64
- p.valDec = (*Buffer).DecodeZigzag64
- p.valSize = sizeZigzag64
- case "bytes", "group":
- p.WireType = WireBytes
- // no numeric converter for non-numeric types
- default:
- fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s)
- return
- }
-
- var err error
- p.Tag, err = strconv.Atoi(fields[1])
- if err != nil {
- return
- }
-
- for i := 2; i < len(fields); i++ {
- f := fields[i]
- switch {
- case f == "req":
- p.Required = true
- case f == "opt":
- p.Optional = true
- case f == "rep":
- p.Repeated = true
- case f == "packed":
- p.Packed = true
- case strings.HasPrefix(f, "name="):
- p.OrigName = f[5:]
- case strings.HasPrefix(f, "enum="):
- p.Enum = f[5:]
- case f == "proto3":
- p.proto3 = true
- case strings.HasPrefix(f, "def="):
- p.HasDefault = true
- p.Default = f[4:] // rest of string
- if i+1 < len(fields) {
- // Commas aren't escaped, and def is always last.
- p.Default += "," + strings.Join(fields[i+1:], ",")
- break
- }
- }
- }
-}
-
-func logNoSliceEnc(t1, t2 reflect.Type) {
- fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2)
-}
-
-var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
-
-// Initialize the fields for encoding and decoding.
-func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
- p.enc = nil
- p.dec = nil
- p.size = nil
-
- switch t1 := typ; t1.Kind() {
- default:
- fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1)
-
- // proto3 scalar types
-
- case reflect.Bool:
- p.enc = (*Buffer).enc_proto3_bool
- p.dec = (*Buffer).dec_proto3_bool
- p.size = size_proto3_bool
- case reflect.Int32:
- p.enc = (*Buffer).enc_proto3_int32
- p.dec = (*Buffer).dec_proto3_int32
- p.size = size_proto3_int32
- case reflect.Uint32:
- p.enc = (*Buffer).enc_proto3_uint32
- p.dec = (*Buffer).dec_proto3_int32 // can reuse
- p.size = size_proto3_uint32
- case reflect.Int64, reflect.Uint64:
- p.enc = (*Buffer).enc_proto3_int64
- p.dec = (*Buffer).dec_proto3_int64
- p.size = size_proto3_int64
- case reflect.Float32:
- p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits
- p.dec = (*Buffer).dec_proto3_int32
- p.size = size_proto3_uint32
- case reflect.Float64:
- p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits
- p.dec = (*Buffer).dec_proto3_int64
- p.size = size_proto3_int64
- case reflect.String:
- p.enc = (*Buffer).enc_proto3_string
- p.dec = (*Buffer).dec_proto3_string
- p.size = size_proto3_string
-
- case reflect.Ptr:
- switch t2 := t1.Elem(); t2.Kind() {
- default:
- fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2)
- break
- case reflect.Bool:
- p.enc = (*Buffer).enc_bool
- p.dec = (*Buffer).dec_bool
- p.size = size_bool
- case reflect.Int32:
- p.enc = (*Buffer).enc_int32
- p.dec = (*Buffer).dec_int32
- p.size = size_int32
- case reflect.Uint32:
- p.enc = (*Buffer).enc_uint32
- p.dec = (*Buffer).dec_int32 // can reuse
- p.size = size_uint32
- case reflect.Int64, reflect.Uint64:
- p.enc = (*Buffer).enc_int64
- p.dec = (*Buffer).dec_int64
- p.size = size_int64
- case reflect.Float32:
- p.enc = (*Buffer).enc_uint32 // can just treat them as bits
- p.dec = (*Buffer).dec_int32
- p.size = size_uint32
- case reflect.Float64:
- p.enc = (*Buffer).enc_int64 // can just treat them as bits
- p.dec = (*Buffer).dec_int64
- p.size = size_int64
- case reflect.String:
- p.enc = (*Buffer).enc_string
- p.dec = (*Buffer).dec_string
- p.size = size_string
- case reflect.Struct:
- p.stype = t1.Elem()
- p.isMarshaler = isMarshaler(t1)
- p.isUnmarshaler = isUnmarshaler(t1)
- if p.Wire == "bytes" {
- p.enc = (*Buffer).enc_struct_message
- p.dec = (*Buffer).dec_struct_message
- p.size = size_struct_message
- } else {
- p.enc = (*Buffer).enc_struct_group
- p.dec = (*Buffer).dec_struct_group
- p.size = size_struct_group
- }
- }
-
- case reflect.Slice:
- switch t2 := t1.Elem(); t2.Kind() {
- default:
- logNoSliceEnc(t1, t2)
- break
- case reflect.Bool:
- if p.Packed {
- p.enc = (*Buffer).enc_slice_packed_bool
- p.size = size_slice_packed_bool
- } else {
- p.enc = (*Buffer).enc_slice_bool
- p.size = size_slice_bool
- }
- p.dec = (*Buffer).dec_slice_bool
- p.packedDec = (*Buffer).dec_slice_packed_bool
- case reflect.Int32:
- if p.Packed {
- p.enc = (*Buffer).enc_slice_packed_int32
- p.size = size_slice_packed_int32
- } else {
- p.enc = (*Buffer).enc_slice_int32
- p.size = size_slice_int32
- }
- p.dec = (*Buffer).dec_slice_int32
- p.packedDec = (*Buffer).dec_slice_packed_int32
- case reflect.Uint32:
- if p.Packed {
- p.enc = (*Buffer).enc_slice_packed_uint32
- p.size = size_slice_packed_uint32
- } else {
- p.enc = (*Buffer).enc_slice_uint32
- p.size = size_slice_uint32
- }
- p.dec = (*Buffer).dec_slice_int32
- p.packedDec = (*Buffer).dec_slice_packed_int32
- case reflect.Int64, reflect.Uint64:
- if p.Packed {
- p.enc = (*Buffer).enc_slice_packed_int64
- p.size = size_slice_packed_int64
- } else {
- p.enc = (*Buffer).enc_slice_int64
- p.size = size_slice_int64
- }
- p.dec = (*Buffer).dec_slice_int64
- p.packedDec = (*Buffer).dec_slice_packed_int64
- case reflect.Uint8:
- p.enc = (*Buffer).enc_slice_byte
- p.dec = (*Buffer).dec_slice_byte
- p.size = size_slice_byte
- if p.proto3 {
- p.enc = (*Buffer).enc_proto3_slice_byte
- p.size = size_proto3_slice_byte
- }
- case reflect.Float32, reflect.Float64:
- switch t2.Bits() {
- case 32:
- // can just treat them as bits
- if p.Packed {
- p.enc = (*Buffer).enc_slice_packed_uint32
- p.size = size_slice_packed_uint32
- } else {
- p.enc = (*Buffer).enc_slice_uint32
- p.size = size_slice_uint32
- }
- p.dec = (*Buffer).dec_slice_int32
- p.packedDec = (*Buffer).dec_slice_packed_int32
- case 64:
- // can just treat them as bits
- if p.Packed {
- p.enc = (*Buffer).enc_slice_packed_int64
- p.size = size_slice_packed_int64
- } else {
- p.enc = (*Buffer).enc_slice_int64
- p.size = size_slice_int64
- }
- p.dec = (*Buffer).dec_slice_int64
- p.packedDec = (*Buffer).dec_slice_packed_int64
- default:
- logNoSliceEnc(t1, t2)
- break
- }
- case reflect.String:
- p.enc = (*Buffer).enc_slice_string
- p.dec = (*Buffer).dec_slice_string
- p.size = size_slice_string
- case reflect.Ptr:
- switch t3 := t2.Elem(); t3.Kind() {
- default:
- fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3)
- break
- case reflect.Struct:
- p.stype = t2.Elem()
- p.isMarshaler = isMarshaler(t2)
- p.isUnmarshaler = isUnmarshaler(t2)
- if p.Wire == "bytes" {
- p.enc = (*Buffer).enc_slice_struct_message
- p.dec = (*Buffer).dec_slice_struct_message
- p.size = size_slice_struct_message
- } else {
- p.enc = (*Buffer).enc_slice_struct_group
- p.dec = (*Buffer).dec_slice_struct_group
- p.size = size_slice_struct_group
- }
- }
- case reflect.Slice:
- switch t2.Elem().Kind() {
- default:
- fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem())
- break
- case reflect.Uint8:
- p.enc = (*Buffer).enc_slice_slice_byte
- p.dec = (*Buffer).dec_slice_slice_byte
- p.size = size_slice_slice_byte
- }
- }
-
- case reflect.Map:
- p.enc = (*Buffer).enc_new_map
- p.dec = (*Buffer).dec_new_map
- p.size = size_new_map
-
- p.mtype = t1
- p.mkeyprop = &Properties{}
- p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
- p.mvalprop = &Properties{}
- vtype := p.mtype.Elem()
- if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
- // The value type is not a message (*T) or bytes ([]byte),
- // so we need encoders for the pointer to this type.
- vtype = reflect.PtrTo(vtype)
- }
- p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
- }
-
- // precalculate tag code
- wire := p.WireType
- if p.Packed {
- wire = WireBytes
- }
- x := uint32(p.Tag)<<3 | uint32(wire)
- i := 0
- for i = 0; x > 127; i++ {
- p.tagbuf[i] = 0x80 | uint8(x&0x7F)
- x >>= 7
- }
- p.tagbuf[i] = uint8(x)
- p.tagcode = p.tagbuf[0 : i+1]
-
- if p.stype != nil {
- if lockGetProp {
- p.sprop = GetProperties(p.stype)
- } else {
- p.sprop = getPropertiesLocked(p.stype)
- }
- }
-}
-
-var (
- marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
- unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
-)
-
-// isMarshaler reports whether type t implements Marshaler.
-func isMarshaler(t reflect.Type) bool {
- // We're checking for (likely) pointer-receiver methods
- // so if t is not a pointer, something is very wrong.
- // The calls above only invoke isMarshaler on pointer types.
- if t.Kind() != reflect.Ptr {
- panic("proto: misuse of isMarshaler")
- }
- return t.Implements(marshalerType)
-}
-
-// isUnmarshaler reports whether type t implements Unmarshaler.
-func isUnmarshaler(t reflect.Type) bool {
- // We're checking for (likely) pointer-receiver methods
- // so if t is not a pointer, something is very wrong.
- // The calls above only invoke isUnmarshaler on pointer types.
- if t.Kind() != reflect.Ptr {
- panic("proto: misuse of isUnmarshaler")
- }
- return t.Implements(unmarshalerType)
-}
-
-// Init populates the properties from a protocol buffer struct tag.
-func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
- p.init(typ, name, tag, f, true)
-}
-
-func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
- // "bytes,49,opt,def=hello!"
- p.Name = name
- p.OrigName = name
- if f != nil {
- p.field = toField(f)
- }
- if tag == "" {
- return
- }
- p.Parse(tag)
- p.setEncAndDec(typ, f, lockGetProp)
-}
-
-var (
- propertiesMu sync.RWMutex
- propertiesMap = make(map[reflect.Type]*StructProperties)
-)
-
-// GetProperties returns the list of properties for the type represented by t.
-// t must represent a generated struct type of a protocol message.
-func GetProperties(t reflect.Type) *StructProperties {
- if t.Kind() != reflect.Struct {
- panic("proto: type must have kind struct")
- }
-
- // Most calls to GetProperties in a long-running program will be
- // retrieving details for types we have seen before.
- propertiesMu.RLock()
- sprop, ok := propertiesMap[t]
- propertiesMu.RUnlock()
- if ok {
- if collectStats {
- stats.Chit++
- }
- return sprop
- }
-
- propertiesMu.Lock()
- sprop = getPropertiesLocked(t)
- propertiesMu.Unlock()
- return sprop
-}
-
-// getPropertiesLocked requires that propertiesMu is held.
-func getPropertiesLocked(t reflect.Type) *StructProperties {
- if prop, ok := propertiesMap[t]; ok {
- if collectStats {
- stats.Chit++
- }
- return prop
- }
- if collectStats {
- stats.Cmiss++
- }
-
- prop := new(StructProperties)
- // in case of recursive protos, fill this in now.
- propertiesMap[t] = prop
-
- // build properties
- prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType)
- prop.unrecField = invalidField
- prop.Prop = make([]*Properties, t.NumField())
- prop.order = make([]int, t.NumField())
-
- for i := 0; i < t.NumField(); i++ {
- f := t.Field(i)
- p := new(Properties)
- name := f.Name
- p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
-
- if f.Name == "XXX_extensions" { // special case
- p.enc = (*Buffer).enc_map
- p.dec = nil // not needed
- p.size = size_map
- }
- if f.Name == "XXX_unrecognized" { // special case
- prop.unrecField = toField(&f)
- }
- prop.Prop[i] = p
- prop.order[i] = i
- if debug {
- print(i, " ", f.Name, " ", t.String(), " ")
- if p.Tag > 0 {
- print(p.String())
- }
- print("\n")
- }
- if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") {
- fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
- }
- }
-
- // Re-order prop.order.
- sort.Sort(prop)
-
- // build required counts
- // build tags
- reqCount := 0
- prop.decoderOrigNames = make(map[string]int)
- for i, p := range prop.Prop {
- if strings.HasPrefix(p.Name, "XXX_") {
- // Internal fields should not appear in tags/origNames maps.
- // They are handled specially when encoding and decoding.
- continue
- }
- if p.Required {
- reqCount++
- }
- prop.decoderTags.put(p.Tag, i)
- prop.decoderOrigNames[p.OrigName] = i
- }
- prop.reqCount = reqCount
-
- return prop
-}
-
-// Return the Properties object for the x[0]'th field of the structure.
-func propByIndex(t reflect.Type, x []int) *Properties {
- if len(x) != 1 {
- fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t)
- return nil
- }
- prop := GetProperties(t)
- return prop.Prop[x[0]]
-}
-
-// Get the address and type of a pointer to a struct from an interface.
-func getbase(pb Message) (t reflect.Type, b structPointer, err error) {
- if pb == nil {
- err = ErrNil
- return
- }
- // get the reflect type of the pointer to the struct.
- t = reflect.TypeOf(pb)
- // get the address of the struct.
- value := reflect.ValueOf(pb)
- b = toStructPointer(value)
- return
-}
-
-// A global registry of enum types.
-// The generated code will register the generated maps by calling RegisterEnum.
-
-var enumValueMaps = make(map[string]map[string]int32)
-
-// RegisterEnum is called from the generated code to install the enum descriptor
-// maps into the global table to aid parsing text format protocol buffers.
-func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
- if _, ok := enumValueMaps[typeName]; ok {
- panic("proto: duplicate enum registered: " + typeName)
- }
- enumValueMaps[typeName] = valueMap
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/Makefile b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/Makefile
deleted file mode 100644
index 75144b58..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-# Go support for Protocol Buffers - Google's data interchange format
-#
-# Copyright 2014 The Go Authors. All rights reserved.
-# https://github.com/golang/protobuf
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-include ../../Make.protobuf
-
-all: regenerate
-
-regenerate:
- rm -f proto3.pb.go
- make proto3.pb.go
-
-# The following rules are just aids to development. Not needed for typical testing.
-
-diff: regenerate
- git diff proto3.pb.go
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/proto3.proto b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/proto3.proto
deleted file mode 100644
index 3e327ded..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/proto3.proto
+++ /dev/null
@@ -1,58 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2014 The Go Authors. All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package proto3_proto;
-
-message Message {
- enum Humour {
- UNKNOWN = 0;
- PUNS = 1;
- SLAPSTICK = 2;
- BILL_BAILEY = 3;
- }
-
- string name = 1;
- Humour hilarity = 2;
- uint32 height_in_cm = 3;
- bytes data = 4;
- int64 result_count = 7;
- bool true_scotsman = 8;
- float score = 9;
-
- repeated uint64 key = 5;
- Nested nested = 6;
-}
-
-message Nested {
- string bunny = 1;
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/text.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/text.go
deleted file mode 100644
index 720eac47..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/text.go
+++ /dev/null
@@ -1,789 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2010 The Go Authors. All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package proto
-
-// Functions for writing the text protocol buffer format.
-
-import (
- "bufio"
- "bytes"
- "encoding"
- "fmt"
- "io"
- "log"
- "math"
- "os"
- "reflect"
- "sort"
- "strings"
-)
-
-var (
- newline = []byte("\n")
- spaces = []byte(" ")
- gtNewline = []byte(">\n")
- endBraceNewline = []byte("}\n")
- backslashN = []byte{'\\', 'n'}
- backslashR = []byte{'\\', 'r'}
- backslashT = []byte{'\\', 't'}
- backslashDQ = []byte{'\\', '"'}
- backslashBS = []byte{'\\', '\\'}
- posInf = []byte("inf")
- negInf = []byte("-inf")
- nan = []byte("nan")
-)
-
-type writer interface {
- io.Writer
- WriteByte(byte) error
-}
-
-// textWriter is an io.Writer that tracks its indentation level.
-type textWriter struct {
- ind int
- complete bool // if the current position is a complete line
- compact bool // whether to write out as a one-liner
- w writer
-}
-
-func (w *textWriter) WriteString(s string) (n int, err error) {
- if !strings.Contains(s, "\n") {
- if !w.compact && w.complete {
- w.writeIndent()
- }
- w.complete = false
- return io.WriteString(w.w, s)
- }
- // WriteString is typically called without newlines, so this
- // codepath and its copy are rare. We copy to avoid
- // duplicating all of Write's logic here.
- return w.Write([]byte(s))
-}
-
-func (w *textWriter) Write(p []byte) (n int, err error) {
- newlines := bytes.Count(p, newline)
- if newlines == 0 {
- if !w.compact && w.complete {
- w.writeIndent()
- }
- n, err = w.w.Write(p)
- w.complete = false
- return n, err
- }
-
- frags := bytes.SplitN(p, newline, newlines+1)
- if w.compact {
- for i, frag := range frags {
- if i > 0 {
- if err := w.w.WriteByte(' '); err != nil {
- return n, err
- }
- n++
- }
- nn, err := w.w.Write(frag)
- n += nn
- if err != nil {
- return n, err
- }
- }
- return n, nil
- }
-
- for i, frag := range frags {
- if w.complete {
- w.writeIndent()
- }
- nn, err := w.w.Write(frag)
- n += nn
- if err != nil {
- return n, err
- }
- if i+1 < len(frags) {
- if err := w.w.WriteByte('\n'); err != nil {
- return n, err
- }
- n++
- }
- }
- w.complete = len(frags[len(frags)-1]) == 0
- return n, nil
-}
-
-func (w *textWriter) WriteByte(c byte) error {
- if w.compact && c == '\n' {
- c = ' '
- }
- if !w.compact && w.complete {
- w.writeIndent()
- }
- err := w.w.WriteByte(c)
- w.complete = c == '\n'
- return err
-}
-
-func (w *textWriter) indent() { w.ind++ }
-
-func (w *textWriter) unindent() {
- if w.ind == 0 {
- log.Printf("proto: textWriter unindented too far")
- return
- }
- w.ind--
-}
-
-func writeName(w *textWriter, props *Properties) error {
- if _, err := w.WriteString(props.OrigName); err != nil {
- return err
- }
- if props.Wire != "group" {
- return w.WriteByte(':')
- }
- return nil
-}
-
-var (
- messageSetType = reflect.TypeOf((*MessageSet)(nil)).Elem()
-)
-
-// raw is the interface satisfied by RawMessage.
-type raw interface {
- Bytes() []byte
-}
-
-func writeStruct(w *textWriter, sv reflect.Value) error {
- if sv.Type() == messageSetType {
- return writeMessageSet(w, sv.Addr().Interface().(*MessageSet))
- }
-
- st := sv.Type()
- sprops := GetProperties(st)
- for i := 0; i < sv.NumField(); i++ {
- fv := sv.Field(i)
- props := sprops.Prop[i]
- name := st.Field(i).Name
-
- if strings.HasPrefix(name, "XXX_") {
- // There are two XXX_ fields:
- // XXX_unrecognized []byte
- // XXX_extensions map[int32]proto.Extension
- // The first is handled here;
- // the second is handled at the bottom of this function.
- if name == "XXX_unrecognized" && !fv.IsNil() {
- if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil {
- return err
- }
- }
- continue
- }
- if fv.Kind() == reflect.Ptr && fv.IsNil() {
- // Field not filled in. This could be an optional field or
- // a required field that wasn't filled in. Either way, there
- // isn't anything we can show for it.
- continue
- }
- if fv.Kind() == reflect.Slice && fv.IsNil() {
- // Repeated field that is empty, or a bytes field that is unused.
- continue
- }
-
- if props.Repeated && fv.Kind() == reflect.Slice {
- // Repeated field.
- for j := 0; j < fv.Len(); j++ {
- if err := writeName(w, props); err != nil {
- return err
- }
- if !w.compact {
- if err := w.WriteByte(' '); err != nil {
- return err
- }
- }
- v := fv.Index(j)
- if v.Kind() == reflect.Ptr && v.IsNil() {
- // A nil message in a repeated field is not valid,
- // but we can handle that more gracefully than panicking.
- if _, err := w.Write([]byte("\n")); err != nil {
- return err
- }
- continue
- }
- if err := writeAny(w, v, props); err != nil {
- return err
- }
- if err := w.WriteByte('\n'); err != nil {
- return err
- }
- }
- continue
- }
- if fv.Kind() == reflect.Map {
- // Map fields are rendered as a repeated struct with key/value fields.
- keys := fv.MapKeys() // TODO: should we sort these for deterministic output?
- sort.Sort(mapKeys(keys))
- for _, key := range keys {
- val := fv.MapIndex(key)
- if err := writeName(w, props); err != nil {
- return err
- }
- if !w.compact {
- if err := w.WriteByte(' '); err != nil {
- return err
- }
- }
- // open struct
- if err := w.WriteByte('<'); err != nil {
- return err
- }
- if !w.compact {
- if err := w.WriteByte('\n'); err != nil {
- return err
- }
- }
- w.indent()
- // key
- if _, err := w.WriteString("key:"); err != nil {
- return err
- }
- if !w.compact {
- if err := w.WriteByte(' '); err != nil {
- return err
- }
- }
- if err := writeAny(w, key, props.mkeyprop); err != nil {
- return err
- }
- if err := w.WriteByte('\n'); err != nil {
- return err
- }
- // value
- if _, err := w.WriteString("value:"); err != nil {
- return err
- }
- if !w.compact {
- if err := w.WriteByte(' '); err != nil {
- return err
- }
- }
- if err := writeAny(w, val, props.mvalprop); err != nil {
- return err
- }
- if err := w.WriteByte('\n'); err != nil {
- return err
- }
- // close struct
- w.unindent()
- if err := w.WriteByte('>'); err != nil {
- return err
- }
- if err := w.WriteByte('\n'); err != nil {
- return err
- }
- }
- continue
- }
- if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 {
- // empty bytes field
- continue
- }
- if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
- // proto3 non-repeated scalar field; skip if zero value
- switch fv.Kind() {
- case reflect.Bool:
- if !fv.Bool() {
- continue
- }
- case reflect.Int32, reflect.Int64:
- if fv.Int() == 0 {
- continue
- }
- case reflect.Uint32, reflect.Uint64:
- if fv.Uint() == 0 {
- continue
- }
- case reflect.Float32, reflect.Float64:
- if fv.Float() == 0 {
- continue
- }
- case reflect.String:
- if fv.String() == "" {
- continue
- }
- }
- }
-
- if err := writeName(w, props); err != nil {
- return err
- }
- if !w.compact {
- if err := w.WriteByte(' '); err != nil {
- return err
- }
- }
- if b, ok := fv.Interface().(raw); ok {
- if err := writeRaw(w, b.Bytes()); err != nil {
- return err
- }
- continue
- }
-
- // Enums have a String method, so writeAny will work fine.
- if err := writeAny(w, fv, props); err != nil {
- return err
- }
-
- if err := w.WriteByte('\n'); err != nil {
- return err
- }
- }
-
- // Extensions (the XXX_extensions field).
- pv := sv.Addr()
- if pv.Type().Implements(extendableProtoType) {
- if err := writeExtensions(w, pv); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// writeRaw writes an uninterpreted raw message.
-func writeRaw(w *textWriter, b []byte) error {
- if err := w.WriteByte('<'); err != nil {
- return err
- }
- if !w.compact {
- if err := w.WriteByte('\n'); err != nil {
- return err
- }
- }
- w.indent()
- if err := writeUnknownStruct(w, b); err != nil {
- return err
- }
- w.unindent()
- if err := w.WriteByte('>'); err != nil {
- return err
- }
- return nil
-}
-
-// writeAny writes an arbitrary field.
-func writeAny(w *textWriter, v reflect.Value, props *Properties) error {
- v = reflect.Indirect(v)
-
- // Floats have special cases.
- if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {
- x := v.Float()
- var b []byte
- switch {
- case math.IsInf(x, 1):
- b = posInf
- case math.IsInf(x, -1):
- b = negInf
- case math.IsNaN(x):
- b = nan
- }
- if b != nil {
- _, err := w.Write(b)
- return err
- }
- // Other values are handled below.
- }
-
- // We don't attempt to serialise every possible value type; only those
- // that can occur in protocol buffers.
- switch v.Kind() {
- case reflect.Slice:
- // Should only be a []byte; repeated fields are handled in writeStruct.
- if err := writeString(w, string(v.Interface().([]byte))); err != nil {
- return err
- }
- case reflect.String:
- if err := writeString(w, v.String()); err != nil {
- return err
- }
- case reflect.Struct:
- // Required/optional group/message.
- var bra, ket byte = '<', '>'
- if props != nil && props.Wire == "group" {
- bra, ket = '{', '}'
- }
- if err := w.WriteByte(bra); err != nil {
- return err
- }
- if !w.compact {
- if err := w.WriteByte('\n'); err != nil {
- return err
- }
- }
- w.indent()
- if tm, ok := v.Interface().(encoding.TextMarshaler); ok {
- text, err := tm.MarshalText()
- if err != nil {
- return err
- }
- if _, err = w.Write(text); err != nil {
- return err
- }
- } else if err := writeStruct(w, v); err != nil {
- return err
- }
- w.unindent()
- if err := w.WriteByte(ket); err != nil {
- return err
- }
- default:
- _, err := fmt.Fprint(w, v.Interface())
- return err
- }
- return nil
-}
-
-// equivalent to C's isprint.
-func isprint(c byte) bool {
- return c >= 0x20 && c < 0x7f
-}
-
-// writeString writes a string in the protocol buffer text format.
-// It is similar to strconv.Quote except we don't use Go escape sequences,
-// we treat the string as a byte sequence, and we use octal escapes.
-// These differences are to maintain interoperability with the other
-// languages' implementations of the text format.
-func writeString(w *textWriter, s string) error {
- // use WriteByte here to get any needed indent
- if err := w.WriteByte('"'); err != nil {
- return err
- }
- // Loop over the bytes, not the runes.
- for i := 0; i < len(s); i++ {
- var err error
- // Divergence from C++: we don't escape apostrophes.
- // There's no need to escape them, and the C++ parser
- // copes with a naked apostrophe.
- switch c := s[i]; c {
- case '\n':
- _, err = w.w.Write(backslashN)
- case '\r':
- _, err = w.w.Write(backslashR)
- case '\t':
- _, err = w.w.Write(backslashT)
- case '"':
- _, err = w.w.Write(backslashDQ)
- case '\\':
- _, err = w.w.Write(backslashBS)
- default:
- if isprint(c) {
- err = w.w.WriteByte(c)
- } else {
- _, err = fmt.Fprintf(w.w, "\\%03o", c)
- }
- }
- if err != nil {
- return err
- }
- }
- return w.WriteByte('"')
-}
-
-func writeMessageSet(w *textWriter, ms *MessageSet) error {
- for _, item := range ms.Item {
- id := *item.TypeId
- if msd, ok := messageSetMap[id]; ok {
- // Known message set type.
- if _, err := fmt.Fprintf(w, "[%s]: <\n", msd.name); err != nil {
- return err
- }
- w.indent()
-
- pb := reflect.New(msd.t.Elem())
- if err := Unmarshal(item.Message, pb.Interface().(Message)); err != nil {
- if _, err := fmt.Fprintf(w, "/* bad message: %v */\n", err); err != nil {
- return err
- }
- } else {
- if err := writeStruct(w, pb.Elem()); err != nil {
- return err
- }
- }
- } else {
- // Unknown type.
- if _, err := fmt.Fprintf(w, "[%d]: <\n", id); err != nil {
- return err
- }
- w.indent()
- if err := writeUnknownStruct(w, item.Message); err != nil {
- return err
- }
- }
- w.unindent()
- if _, err := w.Write(gtNewline); err != nil {
- return err
- }
- }
- return nil
-}
-
-func writeUnknownStruct(w *textWriter, data []byte) (err error) {
- if !w.compact {
- if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {
- return err
- }
- }
- b := NewBuffer(data)
- for b.index < len(b.buf) {
- x, err := b.DecodeVarint()
- if err != nil {
- _, err := fmt.Fprintf(w, "/* %v */\n", err)
- return err
- }
- wire, tag := x&7, x>>3
- if wire == WireEndGroup {
- w.unindent()
- if _, err := w.Write(endBraceNewline); err != nil {
- return err
- }
- continue
- }
- if _, err := fmt.Fprint(w, tag); err != nil {
- return err
- }
- if wire != WireStartGroup {
- if err := w.WriteByte(':'); err != nil {
- return err
- }
- }
- if !w.compact || wire == WireStartGroup {
- if err := w.WriteByte(' '); err != nil {
- return err
- }
- }
- switch wire {
- case WireBytes:
- buf, e := b.DecodeRawBytes(false)
- if e == nil {
- _, err = fmt.Fprintf(w, "%q", buf)
- } else {
- _, err = fmt.Fprintf(w, "/* %v */", e)
- }
- case WireFixed32:
- x, err = b.DecodeFixed32()
- err = writeUnknownInt(w, x, err)
- case WireFixed64:
- x, err = b.DecodeFixed64()
- err = writeUnknownInt(w, x, err)
- case WireStartGroup:
- err = w.WriteByte('{')
- w.indent()
- case WireVarint:
- x, err = b.DecodeVarint()
- err = writeUnknownInt(w, x, err)
- default:
- _, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire)
- }
- if err != nil {
- return err
- }
- if err = w.WriteByte('\n'); err != nil {
- return err
- }
- }
- return nil
-}
-
-func writeUnknownInt(w *textWriter, x uint64, err error) error {
- if err == nil {
- _, err = fmt.Fprint(w, x)
- } else {
- _, err = fmt.Fprintf(w, "/* %v */", err)
- }
- return err
-}
-
-type int32Slice []int32
-
-func (s int32Slice) Len() int { return len(s) }
-func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
-func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
-
-// writeExtensions writes all the extensions in pv.
-// pv is assumed to be a pointer to a protocol message struct that is extendable.
-func writeExtensions(w *textWriter, pv reflect.Value) error {
- emap := extensionMaps[pv.Type().Elem()]
- ep := pv.Interface().(extendableProto)
-
- // Order the extensions by ID.
- // This isn't strictly necessary, but it will give us
- // canonical output, which will also make testing easier.
- m := ep.ExtensionMap()
- ids := make([]int32, 0, len(m))
- for id := range m {
- ids = append(ids, id)
- }
- sort.Sort(int32Slice(ids))
-
- for _, extNum := range ids {
- ext := m[extNum]
- var desc *ExtensionDesc
- if emap != nil {
- desc = emap[extNum]
- }
- if desc == nil {
- // Unknown extension.
- if err := writeUnknownStruct(w, ext.enc); err != nil {
- return err
- }
- continue
- }
-
- pb, err := GetExtension(ep, desc)
- if err != nil {
- if _, err := fmt.Fprintln(os.Stderr, "proto: failed getting extension: ", err); err != nil {
- return err
- }
- continue
- }
-
- // Repeated extensions will appear as a slice.
- if !desc.repeated() {
- if err := writeExtension(w, desc.Name, pb); err != nil {
- return err
- }
- } else {
- v := reflect.ValueOf(pb)
- for i := 0; i < v.Len(); i++ {
- if err := writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
- return err
- }
- }
- }
- }
- return nil
-}
-
-func writeExtension(w *textWriter, name string, pb interface{}) error {
- if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {
- return err
- }
- if !w.compact {
- if err := w.WriteByte(' '); err != nil {
- return err
- }
- }
- if err := writeAny(w, reflect.ValueOf(pb), nil); err != nil {
- return err
- }
- if err := w.WriteByte('\n'); err != nil {
- return err
- }
- return nil
-}
-
-func (w *textWriter) writeIndent() {
- if !w.complete {
- return
- }
- remain := w.ind * 2
- for remain > 0 {
- n := remain
- if n > len(spaces) {
- n = len(spaces)
- }
- w.w.Write(spaces[:n])
- remain -= n
- }
- w.complete = false
-}
-
-func marshalText(w io.Writer, pb Message, compact bool) error {
- val := reflect.ValueOf(pb)
- if pb == nil || val.IsNil() {
- w.Write([]byte(""))
- return nil
- }
- var bw *bufio.Writer
- ww, ok := w.(writer)
- if !ok {
- bw = bufio.NewWriter(w)
- ww = bw
- }
- aw := &textWriter{
- w: ww,
- complete: true,
- compact: compact,
- }
-
- if tm, ok := pb.(encoding.TextMarshaler); ok {
- text, err := tm.MarshalText()
- if err != nil {
- return err
- }
- if _, err = aw.Write(text); err != nil {
- return err
- }
- if bw != nil {
- return bw.Flush()
- }
- return nil
- }
- // Dereference the received pointer so we don't have outer < and >.
- v := reflect.Indirect(val)
- if err := writeStruct(aw, v); err != nil {
- return err
- }
- if bw != nil {
- return bw.Flush()
- }
- return nil
-}
-
-// MarshalText writes a given protocol buffer in text format.
-// The only errors returned are from w.
-func MarshalText(w io.Writer, pb Message) error {
- return marshalText(w, pb, false)
-}
-
-// MarshalTextString is the same as MarshalText, but returns the string directly.
-func MarshalTextString(pb Message) string {
- var buf bytes.Buffer
- marshalText(&buf, pb, false)
- return buf.String()
-}
-
-// CompactText writes a given protocol buffer in compact text format (one line).
-func CompactText(w io.Writer, pb Message) error { return marshalText(w, pb, true) }
-
-// CompactTextString is the same as CompactText, but returns the string directly.
-func CompactTextString(pb Message) string {
- var buf bytes.Buffer
- marshalText(&buf, pb, true)
- return buf.String()
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/text_parser.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/text_parser.go
deleted file mode 100644
index d1caeff5..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/golang/protobuf/proto/text_parser.go
+++ /dev/null
@@ -1,757 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2010 The Go Authors. All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package proto
-
-// Functions for parsing the Text protocol buffer format.
-// TODO: message sets.
-
-import (
- "encoding"
- "errors"
- "fmt"
- "reflect"
- "strconv"
- "strings"
- "unicode/utf8"
-)
-
-type ParseError struct {
- Message string
- Line int // 1-based line number
- Offset int // 0-based byte offset from start of input
-}
-
-func (p *ParseError) Error() string {
- if p.Line == 1 {
- // show offset only for first line
- return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message)
- }
- return fmt.Sprintf("line %d: %v", p.Line, p.Message)
-}
-
-type token struct {
- value string
- err *ParseError
- line int // line number
- offset int // byte number from start of input, not start of line
- unquoted string // the unquoted version of value, if it was a quoted string
-}
-
-func (t *token) String() string {
- if t.err == nil {
- return fmt.Sprintf("%q (line=%d, offset=%d)", t.value, t.line, t.offset)
- }
- return fmt.Sprintf("parse error: %v", t.err)
-}
-
-type textParser struct {
- s string // remaining input
- done bool // whether the parsing is finished (success or error)
- backed bool // whether back() was called
- offset, line int
- cur token
-}
-
-func newTextParser(s string) *textParser {
- p := new(textParser)
- p.s = s
- p.line = 1
- p.cur.line = 1
- return p
-}
-
-func (p *textParser) errorf(format string, a ...interface{}) *ParseError {
- pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset}
- p.cur.err = pe
- p.done = true
- return pe
-}
-
-// Numbers and identifiers are matched by [-+._A-Za-z0-9]
-func isIdentOrNumberChar(c byte) bool {
- switch {
- case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z':
- return true
- case '0' <= c && c <= '9':
- return true
- }
- switch c {
- case '-', '+', '.', '_':
- return true
- }
- return false
-}
-
-func isWhitespace(c byte) bool {
- switch c {
- case ' ', '\t', '\n', '\r':
- return true
- }
- return false
-}
-
-func (p *textParser) skipWhitespace() {
- i := 0
- for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') {
- if p.s[i] == '#' {
- // comment; skip to end of line or input
- for i < len(p.s) && p.s[i] != '\n' {
- i++
- }
- if i == len(p.s) {
- break
- }
- }
- if p.s[i] == '\n' {
- p.line++
- }
- i++
- }
- p.offset += i
- p.s = p.s[i:len(p.s)]
- if len(p.s) == 0 {
- p.done = true
- }
-}
-
-func (p *textParser) advance() {
- // Skip whitespace
- p.skipWhitespace()
- if p.done {
- return
- }
-
- // Start of non-whitespace
- p.cur.err = nil
- p.cur.offset, p.cur.line = p.offset, p.line
- p.cur.unquoted = ""
- switch p.s[0] {
- case '<', '>', '{', '}', ':', '[', ']', ';', ',':
- // Single symbol
- p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)]
- case '"', '\'':
- // Quoted string
- i := 1
- for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' {
- if p.s[i] == '\\' && i+1 < len(p.s) {
- // skip escaped char
- i++
- }
- i++
- }
- if i >= len(p.s) || p.s[i] != p.s[0] {
- p.errorf("unmatched quote")
- return
- }
- unq, err := unquoteC(p.s[1:i], rune(p.s[0]))
- if err != nil {
- p.errorf("invalid quoted string %v", p.s[0:i+1])
- return
- }
- p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]
- p.cur.unquoted = unq
- default:
- i := 0
- for i < len(p.s) && isIdentOrNumberChar(p.s[i]) {
- i++
- }
- if i == 0 {
- p.errorf("unexpected byte %#x", p.s[0])
- return
- }
- p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)]
- }
- p.offset += len(p.cur.value)
-}
-
-var (
- errBadUTF8 = errors.New("proto: bad UTF-8")
- errBadHex = errors.New("proto: bad hexadecimal")
-)
-
-func unquoteC(s string, quote rune) (string, error) {
- // This is based on C++'s tokenizer.cc.
- // Despite its name, this is *not* parsing C syntax.
- // For instance, "\0" is an invalid quoted string.
-
- // Avoid allocation in trivial cases.
- simple := true
- for _, r := range s {
- if r == '\\' || r == quote {
- simple = false
- break
- }
- }
- if simple {
- return s, nil
- }
-
- buf := make([]byte, 0, 3*len(s)/2)
- for len(s) > 0 {
- r, n := utf8.DecodeRuneInString(s)
- if r == utf8.RuneError && n == 1 {
- return "", errBadUTF8
- }
- s = s[n:]
- if r != '\\' {
- if r < utf8.RuneSelf {
- buf = append(buf, byte(r))
- } else {
- buf = append(buf, string(r)...)
- }
- continue
- }
-
- ch, tail, err := unescape(s)
- if err != nil {
- return "", err
- }
- buf = append(buf, ch...)
- s = tail
- }
- return string(buf), nil
-}
-
-func unescape(s string) (ch string, tail string, err error) {
- r, n := utf8.DecodeRuneInString(s)
- if r == utf8.RuneError && n == 1 {
- return "", "", errBadUTF8
- }
- s = s[n:]
- switch r {
- case 'a':
- return "\a", s, nil
- case 'b':
- return "\b", s, nil
- case 'f':
- return "\f", s, nil
- case 'n':
- return "\n", s, nil
- case 'r':
- return "\r", s, nil
- case 't':
- return "\t", s, nil
- case 'v':
- return "\v", s, nil
- case '?':
- return "?", s, nil // trigraph workaround
- case '\'', '"', '\\':
- return string(r), s, nil
- case '0', '1', '2', '3', '4', '5', '6', '7', 'x', 'X':
- if len(s) < 2 {
- return "", "", fmt.Errorf(`\%c requires 2 following digits`, r)
- }
- base := 8
- ss := s[:2]
- s = s[2:]
- if r == 'x' || r == 'X' {
- base = 16
- } else {
- ss = string(r) + ss
- }
- i, err := strconv.ParseUint(ss, base, 8)
- if err != nil {
- return "", "", err
- }
- return string([]byte{byte(i)}), s, nil
- case 'u', 'U':
- n := 4
- if r == 'U' {
- n = 8
- }
- if len(s) < n {
- return "", "", fmt.Errorf(`\%c requires %d digits`, r, n)
- }
-
- bs := make([]byte, n/2)
- for i := 0; i < n; i += 2 {
- a, ok1 := unhex(s[i])
- b, ok2 := unhex(s[i+1])
- if !ok1 || !ok2 {
- return "", "", errBadHex
- }
- bs[i/2] = a<<4 | b
- }
- s = s[n:]
- return string(bs), s, nil
- }
- return "", "", fmt.Errorf(`unknown escape \%c`, r)
-}
-
-// Adapted from src/pkg/strconv/quote.go.
-func unhex(b byte) (v byte, ok bool) {
- switch {
- case '0' <= b && b <= '9':
- return b - '0', true
- case 'a' <= b && b <= 'f':
- return b - 'a' + 10, true
- case 'A' <= b && b <= 'F':
- return b - 'A' + 10, true
- }
- return 0, false
-}
-
-// Back off the parser by one token. Can only be done between calls to next().
-// It makes the next advance() a no-op.
-func (p *textParser) back() { p.backed = true }
-
-// Advances the parser and returns the new current token.
-func (p *textParser) next() *token {
- if p.backed || p.done {
- p.backed = false
- return &p.cur
- }
- p.advance()
- if p.done {
- p.cur.value = ""
- } else if len(p.cur.value) > 0 && p.cur.value[0] == '"' {
- // Look for multiple quoted strings separated by whitespace,
- // and concatenate them.
- cat := p.cur
- for {
- p.skipWhitespace()
- if p.done || p.s[0] != '"' {
- break
- }
- p.advance()
- if p.cur.err != nil {
- return &p.cur
- }
- cat.value += " " + p.cur.value
- cat.unquoted += p.cur.unquoted
- }
- p.done = false // parser may have seen EOF, but we want to return cat
- p.cur = cat
- }
- return &p.cur
-}
-
-func (p *textParser) consumeToken(s string) error {
- tok := p.next()
- if tok.err != nil {
- return tok.err
- }
- if tok.value != s {
- p.back()
- return p.errorf("expected %q, found %q", s, tok.value)
- }
- return nil
-}
-
-// Return a RequiredNotSetError indicating which required field was not set.
-func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError {
- st := sv.Type()
- sprops := GetProperties(st)
- for i := 0; i < st.NumField(); i++ {
- if !isNil(sv.Field(i)) {
- continue
- }
-
- props := sprops.Prop[i]
- if props.Required {
- return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)}
- }
- }
- return &RequiredNotSetError{fmt.Sprintf("%v.", st)} // should not happen
-}
-
-// Returns the index in the struct for the named field, as well as the parsed tag properties.
-func structFieldByName(st reflect.Type, name string) (int, *Properties, bool) {
- sprops := GetProperties(st)
- i, ok := sprops.decoderOrigNames[name]
- if ok {
- return i, sprops.Prop[i], true
- }
- return -1, nil, false
-}
-
-// Consume a ':' from the input stream (if the next token is a colon),
-// returning an error if a colon is needed but not present.
-func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError {
- tok := p.next()
- if tok.err != nil {
- return tok.err
- }
- if tok.value != ":" {
- // Colon is optional when the field is a group or message.
- needColon := true
- switch props.Wire {
- case "group":
- needColon = false
- case "bytes":
- // A "bytes" field is either a message, a string, or a repeated field;
- // those three become *T, *string and []T respectively, so we can check for
- // this field being a pointer to a non-string.
- if typ.Kind() == reflect.Ptr {
- // *T or *string
- if typ.Elem().Kind() == reflect.String {
- break
- }
- } else if typ.Kind() == reflect.Slice {
- // []T or []*T
- if typ.Elem().Kind() != reflect.Ptr {
- break
- }
- } else if typ.Kind() == reflect.String {
- // The proto3 exception is for a string field,
- // which requires a colon.
- break
- }
- needColon = false
- }
- if needColon {
- return p.errorf("expected ':', found %q", tok.value)
- }
- p.back()
- }
- return nil
-}
-
-func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
- st := sv.Type()
- reqCount := GetProperties(st).reqCount
- var reqFieldErr error
- fieldSet := make(map[string]bool)
- // A struct is a sequence of "name: value", terminated by one of
- // '>' or '}', or the end of the input. A name may also be
- // "[extension]".
- for {
- tok := p.next()
- if tok.err != nil {
- return tok.err
- }
- if tok.value == terminator {
- break
- }
- if tok.value == "[" {
- // Looks like an extension.
- //
- // TODO: Check whether we need to handle
- // namespace rooted names (e.g. ".something.Foo").
- tok = p.next()
- if tok.err != nil {
- return tok.err
- }
- var desc *ExtensionDesc
- // This could be faster, but it's functional.
- // TODO: Do something smarter than a linear scan.
- for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) {
- if d.Name == tok.value {
- desc = d
- break
- }
- }
- if desc == nil {
- return p.errorf("unrecognized extension %q", tok.value)
- }
- // Check the extension terminator.
- tok = p.next()
- if tok.err != nil {
- return tok.err
- }
- if tok.value != "]" {
- return p.errorf("unrecognized extension terminator %q", tok.value)
- }
-
- props := &Properties{}
- props.Parse(desc.Tag)
-
- typ := reflect.TypeOf(desc.ExtensionType)
- if err := p.checkForColon(props, typ); err != nil {
- return err
- }
-
- rep := desc.repeated()
-
- // Read the extension structure, and set it in
- // the value we're constructing.
- var ext reflect.Value
- if !rep {
- ext = reflect.New(typ).Elem()
- } else {
- ext = reflect.New(typ.Elem()).Elem()
- }
- if err := p.readAny(ext, props); err != nil {
- if _, ok := err.(*RequiredNotSetError); !ok {
- return err
- }
- reqFieldErr = err
- }
- ep := sv.Addr().Interface().(extendableProto)
- if !rep {
- SetExtension(ep, desc, ext.Interface())
- } else {
- old, err := GetExtension(ep, desc)
- var sl reflect.Value
- if err == nil {
- sl = reflect.ValueOf(old) // existing slice
- } else {
- sl = reflect.MakeSlice(typ, 0, 1)
- }
- sl = reflect.Append(sl, ext)
- SetExtension(ep, desc, sl.Interface())
- }
- } else {
- // This is a normal, non-extension field.
- name := tok.value
- fi, props, ok := structFieldByName(st, name)
- if !ok {
- return p.errorf("unknown field name %q in %v", name, st)
- }
-
- dst := sv.Field(fi)
-
- if dst.Kind() == reflect.Map {
- // Consume any colon.
- if err := p.checkForColon(props, dst.Type()); err != nil {
- return err
- }
-
- // Construct the map if it doesn't already exist.
- if dst.IsNil() {
- dst.Set(reflect.MakeMap(dst.Type()))
- }
- key := reflect.New(dst.Type().Key()).Elem()
- val := reflect.New(dst.Type().Elem()).Elem()
-
- // The map entry should be this sequence of tokens:
- // < key : KEY value : VALUE >
- // Technically the "key" and "value" could come in any order,
- // but in practice they won't.
-
- tok := p.next()
- var terminator string
- switch tok.value {
- case "<":
- terminator = ">"
- case "{":
- terminator = "}"
- default:
- return p.errorf("expected '{' or '<', found %q", tok.value)
- }
- if err := p.consumeToken("key"); err != nil {
- return err
- }
- if err := p.consumeToken(":"); err != nil {
- return err
- }
- if err := p.readAny(key, props.mkeyprop); err != nil {
- return err
- }
- if err := p.consumeToken("value"); err != nil {
- return err
- }
- if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil {
- return err
- }
- if err := p.readAny(val, props.mvalprop); err != nil {
- return err
- }
- if err := p.consumeToken(terminator); err != nil {
- return err
- }
-
- dst.SetMapIndex(key, val)
- continue
- }
-
- // Check that it's not already set if it's not a repeated field.
- if !props.Repeated && fieldSet[name] {
- return p.errorf("non-repeated field %q was repeated", name)
- }
-
- if err := p.checkForColon(props, st.Field(fi).Type); err != nil {
- return err
- }
-
- // Parse into the field.
- fieldSet[name] = true
- if err := p.readAny(dst, props); err != nil {
- if _, ok := err.(*RequiredNotSetError); !ok {
- return err
- }
- reqFieldErr = err
- } else if props.Required {
- reqCount--
- }
- }
-
- // For backward compatibility, permit a semicolon or comma after a field.
- tok = p.next()
- if tok.err != nil {
- return tok.err
- }
- if tok.value != ";" && tok.value != "," {
- p.back()
- }
- }
-
- if reqCount > 0 {
- return p.missingRequiredFieldError(sv)
- }
- return reqFieldErr
-}
-
-func (p *textParser) readAny(v reflect.Value, props *Properties) error {
- tok := p.next()
- if tok.err != nil {
- return tok.err
- }
- if tok.value == "" {
- return p.errorf("unexpected EOF")
- }
-
- switch fv := v; fv.Kind() {
- case reflect.Slice:
- at := v.Type()
- if at.Elem().Kind() == reflect.Uint8 {
- // Special case for []byte
- if tok.value[0] != '"' && tok.value[0] != '\'' {
- // Deliberately written out here, as the error after
- // this switch statement would write "invalid []byte: ...",
- // which is not as user-friendly.
- return p.errorf("invalid string: %v", tok.value)
- }
- bytes := []byte(tok.unquoted)
- fv.Set(reflect.ValueOf(bytes))
- return nil
- }
- // Repeated field. May already exist.
- flen := fv.Len()
- if flen == fv.Cap() {
- nav := reflect.MakeSlice(at, flen, 2*flen+1)
- reflect.Copy(nav, fv)
- fv.Set(nav)
- }
- fv.SetLen(flen + 1)
-
- // Read one.
- p.back()
- return p.readAny(fv.Index(flen), props)
- case reflect.Bool:
- // Either "true", "false", 1 or 0.
- switch tok.value {
- case "true", "1":
- fv.SetBool(true)
- return nil
- case "false", "0":
- fv.SetBool(false)
- return nil
- }
- case reflect.Float32, reflect.Float64:
- v := tok.value
- // Ignore 'f' for compatibility with output generated by C++, but don't
- // remove 'f' when the value is "-inf" or "inf".
- if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" {
- v = v[:len(v)-1]
- }
- if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil {
- fv.SetFloat(f)
- return nil
- }
- case reflect.Int32:
- if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil {
- fv.SetInt(x)
- return nil
- }
-
- if len(props.Enum) == 0 {
- break
- }
- m, ok := enumValueMaps[props.Enum]
- if !ok {
- break
- }
- x, ok := m[tok.value]
- if !ok {
- break
- }
- fv.SetInt(int64(x))
- return nil
- case reflect.Int64:
- if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil {
- fv.SetInt(x)
- return nil
- }
-
- case reflect.Ptr:
- // A basic field (indirected through pointer), or a repeated message/group
- p.back()
- fv.Set(reflect.New(fv.Type().Elem()))
- return p.readAny(fv.Elem(), props)
- case reflect.String:
- if tok.value[0] == '"' || tok.value[0] == '\'' {
- fv.SetString(tok.unquoted)
- return nil
- }
- case reflect.Struct:
- var terminator string
- switch tok.value {
- case "{":
- terminator = "}"
- case "<":
- terminator = ">"
- default:
- return p.errorf("expected '{' or '<', found %q", tok.value)
- }
- // TODO: Handle nested messages which implement encoding.TextUnmarshaler.
- return p.readStruct(fv, terminator)
- case reflect.Uint32:
- if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {
- fv.SetUint(uint64(x))
- return nil
- }
- case reflect.Uint64:
- if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil {
- fv.SetUint(x)
- return nil
- }
- }
- return p.errorf("invalid %v: %v", v.Type(), tok.value)
-}
-
-// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb
-// before starting to unmarshal, so any existing data in pb is always removed.
-// If a required field is not set and no other error occurs,
-// UnmarshalText returns *RequiredNotSetError.
-func UnmarshalText(s string, pb Message) error {
- if um, ok := pb.(encoding.TextUnmarshaler); ok {
- err := um.UnmarshalText([]byte(s))
- return err
- }
- pb.Reset()
- v := reflect.ValueOf(pb)
- if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil {
- return pe
- }
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runtime-spec/LICENSE b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runtime-spec/LICENSE
deleted file mode 100644
index bdc40365..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runtime-spec/LICENSE
+++ /dev/null
@@ -1,191 +0,0 @@
-
- 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
-
- Copyright 2015 The Linux Foundation.
-
- 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/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runtime-spec/specs-go/config.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runtime-spec/specs-go/config.go
deleted file mode 100644
index 2daba464..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runtime-spec/specs-go/config.go
+++ /dev/null
@@ -1,419 +0,0 @@
-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.
-type Spec struct {
- // Version is the version of the specification that is supported.
- Version string `json:"ociVersion"`
- // Platform is the host information for OS and Arch.
- Platform Platform `json:"platform"`
- // Process is the container's main process.
- Process Process `json:"process"`
- // Root is the root information for the container's filesystem.
- Root Root `json:"root"`
- // 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"`
- // 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"`
-}
-
-// 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"`
- // User specifies user information for the process.
- User User `json:"user"`
- // Args specifies the binary and arguments for the application to execute.
- Args []string `json:"args"`
- // Env populates the process environment for the process.
- Env []string `json:"env,omitempty"`
- // Cwd is the current working directory for the process and must be
- // relative to the container's root.
- Cwd string `json:"cwd"`
- // Capabilities are Linux capabilities that are kept for the container.
- Capabilities []string `json:"capabilities,omitempty" platform:"linux"`
- // Rlimits specifies rlimit options to apply to the process.
- Rlimits []Rlimit `json:"rlimits,omitempty"`
- // NoNewPrivileges controls whether additional privileges could be gained by processes in the container.
- NoNewPrivileges bool `json:"noNewPrivileges,omitempty"`
-
- // ApparmorProfile specified the apparmor profile for the container. (this field is platform dependent)
- ApparmorProfile string `json:"apparmorProfile,omitempty" platform:"linux"`
- // SelinuxProcessLabel specifies the selinux context that the container process is run as. (this field is platform dependent)
- SelinuxLabel string `json:"selinuxLabel,omitempty" platform:"linux"`
-}
-
-// User specifies Linux specific user and group information for the container's
-// main process.
-type User struct {
- // UID is the user id. (this field is platform dependent)
- UID uint32 `json:"uid,omitempty" platform:"linux"`
- // GID is the group id. (this field is platform dependent)
- GID uint32 `json:"gid,omitempty" 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"`
-}
-
-// Root contains information about the container's root filesystem on the host.
-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"`
-}
-
-// Platform specifies OS and arch information for the host system that the container
-// is created for.
-type Platform struct {
- // OS is the operating system.
- OS string `json:"os"`
- // Arch is the architecture
- Arch string `json:"arch"`
-}
-
-// Mount specifies a mount for a container.
-type Mount struct {
- // Destination is the path where the mount will be placed relative to the container's root. The path and child directories MUST exist, a runtime MUST NOT create directories automatically to a mount point.
- Destination string `json:"destination"`
- // Type specifies the mount kind.
- Type string `json:"type"`
- // Source specifies the source path of the mount. In the case of bind mounts on
- // Linux based systems this would be the file on the host.
- Source string `json:"source"`
- // Options are fstab style mount options.
- Options []string `json:"options,omitempty"`
-}
-
-// Hook specifies a command that is run at a particular event in the lifecycle of a container
-type Hook struct {
- Path string `json:"path"`
- Args []string `json:"args,omitempty"`
- Env []string `json:"env,omitempty"`
- Timeout *int `json:"timeout,omitempty"`
-}
-
-// Hooks for container setup and teardown
-type Hooks struct {
- // Prestart is a list of hooks to be run before the container process is executed.
- // On Linux, they are run after the container namespaces are created.
- Prestart []Hook `json:"prestart,omitempty"`
- // Poststart is a list of hooks to be run after the container process is started.
- Poststart []Hook `json:"poststart,omitempty"`
- // Poststop is a list of hooks to be run after the container process exits.
- Poststop []Hook `json:"poststop,omitempty"`
-}
-
-// Linux contains platform specific configuration for Linux based containers.
-type Linux struct {
- // UIDMapping specifies user mappings for supporting user namespaces on Linux.
- UIDMappings []IDMapping `json:"uidMappings,omitempty"`
- // GIDMapping specifies group mappings for supporting user namespaces on Linux.
- GIDMappings []IDMapping `json:"gidMappings,omitempty"`
- // Sysctl are a set of key value pairs that are set for the container on start
- Sysctl map[string]string `json:"sysctl,omitempty"`
- // Resources contain cgroup information for handling resource constraints
- // for the container
- Resources *Resources `json:"resources,omitempty"`
- // CgroupsPath specifies the path to cgroups that are created and/or joined by the container.
- // The path is expected to be relative to the cgroups mountpoint.
- // If resources are specified, the cgroups at CgroupsPath will be updated based on resources.
- CgroupsPath *string `json:"cgroupsPath,omitempty"`
- // Namespaces contains the namespaces that are created and/or joined by the container
- Namespaces []Namespace `json:"namespaces,omitempty"`
- // Devices are a list of device nodes that are created for the container
- Devices []Device `json:"devices,omitempty"`
- // Seccomp specifies the seccomp security settings for the container.
- Seccomp *Seccomp `json:"seccomp,omitempty"`
- // RootfsPropagation is the rootfs mount propagation mode for the container.
- RootfsPropagation string `json:"rootfsPropagation,omitempty"`
- // MaskedPaths masks over the provided paths inside the container.
- MaskedPaths []string `json:"maskedPaths,omitempty"`
- // ReadonlyPaths sets the provided paths as RO inside the container.
- ReadonlyPaths []string `json:"readonlyPaths,omitempty"`
- // MountLabel specifies the selinux context for the mounts in the container.
- MountLabel string `json:"mountLabel,omitempty"`
-}
-
-// Namespace is the configuration for a Linux namespace
-type Namespace struct {
- // Type is the type of Linux namespace
- Type NamespaceType `json:"type"`
- // Path is a path to an existing namespace persisted on disk that can be joined
- // and is of the same type
- Path string `json:"path,omitempty"`
-}
-
-// NamespaceType is one of the Linux namespaces
-type NamespaceType string
-
-const (
- // PIDNamespace for isolating process IDs
- PIDNamespace NamespaceType = "pid"
- // NetworkNamespace for isolating network devices, stacks, ports, etc
- NetworkNamespace = "network"
- // MountNamespace for isolating mount points
- MountNamespace = "mount"
- // IPCNamespace for isolating System V IPC, POSIX message queues
- IPCNamespace = "ipc"
- // UTSNamespace for isolating hostname and NIS domain name
- UTSNamespace = "uts"
- // UserNamespace for isolating user and group IDs
- UserNamespace = "user"
-)
-
-// IDMapping specifies UID/GID mappings
-type IDMapping struct {
- // HostID is the UID/GID of the host user or group
- HostID uint32 `json:"hostID"`
- // ContainerID is the UID/GID of the container's user or group
- ContainerID uint32 `json:"containerID"`
- // Size is the length of the range of IDs mapped between the two namespaces
- Size uint32 `json:"size"`
-}
-
-// Rlimit type and restrictions
-type Rlimit struct {
- // Type of the rlimit to set
- Type string `json:"type"`
- // Hard is the hard limit for the specified type
- Hard uint64 `json:"hard"`
- // Soft is the soft limit for the specified type
- Soft uint64 `json:"soft"`
-}
-
-// HugepageLimit structure corresponds to limiting kernel hugepages
-type HugepageLimit struct {
- // Pagesize is the hugepage size
- Pagesize *string `json:"pageSize,omitempty"`
- // Limit is the limit of "hugepagesize" hugetlb usage
- Limit *uint64 `json:"limit,omitempty"`
-}
-
-// InterfacePriority for network interfaces
-type InterfacePriority struct {
- // Name is the name of the network interface
- Name string `json:"name"`
- // Priority for the interface
- Priority uint32 `json:"priority"`
-}
-
-// blockIODevice holds major:minor format supported in blkio cgroup
-type blockIODevice struct {
- // Major is the device's major number.
- Major int64 `json:"major"`
- // Minor is the device's minor number.
- Minor int64 `json:"minor"`
-}
-
-// WeightDevice struct holds a `major:minor weight` pair for blkioWeightDevice
-type WeightDevice struct {
- blockIODevice
- // Weight is the bandwidth rate for the device, range is from 10 to 1000
- Weight *uint16 `json:"weight,omitempty"`
- // LeafWeight is the bandwidth rate for the device while competing with the cgroup's child cgroups, range is from 10 to 1000, CFQ scheduler only
- LeafWeight *uint16 `json:"leafWeight,omitempty"`
-}
-
-// ThrottleDevice struct holds a `major:minor rate_per_second` pair
-type ThrottleDevice struct {
- blockIODevice
- // Rate is the IO rate limit per cgroup per device
- Rate *uint64 `json:"rate,omitempty"`
-}
-
-// BlockIO for Linux cgroup 'blkio' resource management
-type BlockIO struct {
- // Specifies per cgroup weight, range is from 10 to 1000
- Weight *uint16 `json:"blkioWeight,omitempty"`
- // Specifies tasks' weight in the given cgroup while competing with the cgroup's child cgroups, range is from 10 to 1000, CFQ scheduler only
- LeafWeight *uint16 `json:"blkioLeafWeight,omitempty"`
- // Weight per cgroup per device, can override BlkioWeight
- WeightDevice []WeightDevice `json:"blkioWeightDevice,omitempty"`
- // IO read rate limit per cgroup per device, bytes per second
- ThrottleReadBpsDevice []ThrottleDevice `json:"blkioThrottleReadBpsDevice,omitempty"`
- // IO write rate limit per cgroup per device, bytes per second
- ThrottleWriteBpsDevice []ThrottleDevice `json:"blkioThrottleWriteBpsDevice,omitempty"`
- // IO read rate limit per cgroup per device, IO per second
- ThrottleReadIOPSDevice []ThrottleDevice `json:"blkioThrottleReadIOPSDevice,omitempty"`
- // IO write rate limit per cgroup per device, IO per second
- ThrottleWriteIOPSDevice []ThrottleDevice `json:"blkioThrottleWriteIOPSDevice,omitempty"`
-}
-
-// Memory for Linux cgroup 'memory' resource management
-type Memory struct {
- // Memory limit (in bytes).
- Limit *uint64 `json:"limit,omitempty"`
- // Memory reservation or soft_limit (in bytes).
- Reservation *uint64 `json:"reservation,omitempty"`
- // Total memory limit (memory + swap).
- Swap *uint64 `json:"swap,omitempty"`
- // Kernel memory limit (in bytes).
- Kernel *uint64 `json:"kernel,omitempty"`
- // Kernel memory limit for tcp (in bytes)
- KernelTCP *uint64 `json:"kernelTCP"`
- // How aggressive the kernel will swap memory pages. Range from 0 to 100.
- Swappiness *uint64 `json:"swappiness,omitempty"`
-}
-
-// CPU for Linux cgroup 'cpu' resource management
-type CPU struct {
- // CPU shares (relative weight (ratio) vs. other cgroups with cpu shares).
- Shares *uint64 `json:"shares,omitempty"`
- // CPU hardcap limit (in usecs). Allowed cpu time in a given period.
- Quota *uint64 `json:"quota,omitempty"`
- // CPU period to be used for hardcapping (in usecs).
- Period *uint64 `json:"period,omitempty"`
- // How much time realtime scheduling may use (in usecs).
- RealtimeRuntime *uint64 `json:"realtimeRuntime,omitempty"`
- // CPU period to be used for realtime scheduling (in usecs).
- RealtimePeriod *uint64 `json:"realtimePeriod,omitempty"`
- // CPUs to use within the cpuset. Default is to use any CPU available.
- Cpus *string `json:"cpus,omitempty"`
- // List of memory nodes in the cpuset. Default is to use any available memory node.
- Mems *string `json:"mems,omitempty"`
-}
-
-// Pids for Linux cgroup 'pids' resource management (Linux 4.3)
-type Pids struct {
- // Maximum number of PIDs. Default is "no limit".
- Limit *int64 `json:"limit,omitempty"`
-}
-
-// Network identification and priority configuration
-type Network struct {
- // Set class identifier for container's network packets
- ClassID *uint32 `json:"classID"`
- // Set priority of network traffic for container
- Priorities []InterfacePriority `json:"priorities,omitempty"`
-}
-
-// Resources has container runtime resource constraints
-type Resources struct {
- // Devices are a list of device rules for the whitelist controller
- Devices []DeviceCgroup `json:"devices"`
- // DisableOOMKiller disables the OOM killer for out of memory conditions
- DisableOOMKiller *bool `json:"disableOOMKiller,omitempty"`
- // Specify an oom_score_adj for the container.
- OOMScoreAdj *int `json:"oomScoreAdj,omitempty"`
- // Memory restriction configuration
- Memory *Memory `json:"memory,omitempty"`
- // CPU resource restriction configuration
- CPU *CPU `json:"cpu,omitempty"`
- // Task resource restriction configuration.
- Pids *Pids `json:"pids,omitempty"`
- // BlockIO restriction configuration
- BlockIO *BlockIO `json:"blockIO,omitempty"`
- // Hugetlb limit (in bytes)
- HugepageLimits []HugepageLimit `json:"hugepageLimits,omitempty"`
- // Network restriction configuration
- Network *Network `json:"network,omitempty"`
-}
-
-// Device represents the mknod information for a Linux special device file
-type Device struct {
- // Path to the device.
- Path string `json:"path"`
- // Device type, block, char, etc.
- Type string `json:"type"`
- // Major is the device's major number.
- Major int64 `json:"major"`
- // Minor is the device's minor number.
- Minor int64 `json:"minor"`
- // FileMode permission bits for the device.
- FileMode *os.FileMode `json:"fileMode,omitempty"`
- // UID of the device.
- UID *uint32 `json:"uid,omitempty"`
- // Gid of the device.
- GID *uint32 `json:"gid,omitempty"`
-}
-
-// DeviceCgroup represents a device rule for the whitelist controller
-type DeviceCgroup struct {
- // Allow or deny
- Allow bool `json:"allow"`
- // Device type, block, char, etc.
- Type *string `json:"type,omitempty"`
- // Major is the device's major number.
- Major *int64 `json:"major,omitempty"`
- // Minor is the device's minor number.
- Minor *int64 `json:"minor,omitempty"`
- // Cgroup access permissions format, rwm.
- Access *string `json:"access,omitempty"`
-}
-
-// Seccomp represents syscall restrictions
-type Seccomp struct {
- DefaultAction Action `json:"defaultAction"`
- Architectures []Arch `json:"architectures"`
- Syscalls []Syscall `json:"syscalls,omitempty"`
-}
-
-// Arch used for additional architectures
-type Arch string
-
-// Additional architectures permitted to be used for system calls
-// By default only the native architecture of the kernel is permitted
-const (
- ArchX86 Arch = "SCMP_ARCH_X86"
- ArchX86_64 Arch = "SCMP_ARCH_X86_64"
- ArchX32 Arch = "SCMP_ARCH_X32"
- ArchARM Arch = "SCMP_ARCH_ARM"
- ArchAARCH64 Arch = "SCMP_ARCH_AARCH64"
- ArchMIPS Arch = "SCMP_ARCH_MIPS"
- ArchMIPS64 Arch = "SCMP_ARCH_MIPS64"
- ArchMIPS64N32 Arch = "SCMP_ARCH_MIPS64N32"
- ArchMIPSEL Arch = "SCMP_ARCH_MIPSEL"
- ArchMIPSEL64 Arch = "SCMP_ARCH_MIPSEL64"
- ArchMIPSEL64N32 Arch = "SCMP_ARCH_MIPSEL64N32"
-)
-
-// Action taken upon Seccomp rule match
-type Action string
-
-// Define actions for Seccomp rules
-const (
- ActKill Action = "SCMP_ACT_KILL"
- ActTrap Action = "SCMP_ACT_TRAP"
- ActErrno Action = "SCMP_ACT_ERRNO"
- ActTrace Action = "SCMP_ACT_TRACE"
- ActAllow Action = "SCMP_ACT_ALLOW"
-)
-
-// Operator used to match syscall arguments in Seccomp
-type Operator string
-
-// Define operators for syscall arguments in Seccomp
-const (
- OpNotEqual Operator = "SCMP_CMP_NE"
- OpLessThan Operator = "SCMP_CMP_LT"
- OpLessEqual Operator = "SCMP_CMP_LE"
- OpEqualTo Operator = "SCMP_CMP_EQ"
- OpGreaterEqual Operator = "SCMP_CMP_GE"
- OpGreaterThan Operator = "SCMP_CMP_GT"
- OpMaskedEqual Operator = "SCMP_CMP_MASKED_EQ"
-)
-
-// Arg used for matching specific syscall arguments in Seccomp
-type Arg struct {
- Index uint `json:"index"`
- Value uint64 `json:"value"`
- ValueTwo uint64 `json:"valueTwo"`
- Op Operator `json:"op"`
-}
-
-// Syscall is used to match a syscall in Seccomp
-type Syscall struct {
- Name string `json:"name"`
- Action Action `json:"action"`
- Args []Arg `json:"args,omitempty"`
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runtime-spec/specs-go/state.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runtime-spec/specs-go/state.go
deleted file mode 100644
index d3ad79d9..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runtime-spec/specs-go/state.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package specs
-
-// State holds information about the runtime state of the container.
-type State struct {
- // Version is the version of the specification that is supported.
- Version string `json:"version"`
- // ID is the container ID
- ID string `json:"id"`
- // 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"`
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runtime-spec/specs-go/version.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runtime-spec/specs-go/version.go
deleted file mode 100644
index 371289ae..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runtime-spec/specs-go/version.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package specs
-
-import "fmt"
-
-const (
- // VersionMajor is for an API incompatible changes
- VersionMajor = 0
- // VersionMinor is for functionality in a backwards-compatible manner
- VersionMinor = 6
- // VersionPatch is for backwards-compatible bug fixes
- VersionPatch = 0
-
- // VersionDev indicates development branch. Releases will be empty string.
- VersionDev = "-dev"
-)
-
-// Version is the specification version that the package types support.
-var Version = fmt.Sprintf("%d.%d.%d%s", VersionMajor, VersionMinor, VersionPatch, VersionDev)
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/LICENSE b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/LICENSE
deleted file mode 100644
index d6456956..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- 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/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/NOTICE b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/NOTICE
deleted file mode 100644
index 405a4961..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/NOTICE
+++ /dev/null
@@ -1,8 +0,0 @@
-ffjson
-Copyright (c) 2014, Paul Querna
-
-This product includes software developed by
-Paul Querna (http://paul.querna.org/).
-
-Portions of this software were developed as
-part of Go, Copyright (c) 2012 The Go Authors.
\ No newline at end of file
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/buffer.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/buffer.go
deleted file mode 100644
index 79bcd084..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/buffer.go
+++ /dev/null
@@ -1,414 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package v1
-
-// Simple byte buffer for marshaling data.
-
-import (
- "bytes"
- "encoding/json"
- "errors"
- "io"
- "unicode/utf8"
-)
-
-type grower interface {
- Grow(n int)
-}
-
-type truncater interface {
- Truncate(n int)
- Reset()
-}
-
-type bytesReader interface {
- Bytes() []byte
- String() string
-}
-
-type runeWriter interface {
- WriteRune(r rune) (n int, err error)
-}
-
-type stringWriter interface {
- WriteString(s string) (n int, err error)
-}
-
-type lener interface {
- Len() int
-}
-
-type rewinder interface {
- Rewind(n int) (err error)
-}
-
-type encoder interface {
- Encode(interface{}) error
-}
-
-// TODO(pquerna): continue to reduce these interfaces
-
-type EncodingBuffer interface {
- io.Writer
- io.WriterTo
- io.ByteWriter
- stringWriter
- truncater
- grower
- rewinder
- encoder
-}
-
-type DecodingBuffer interface {
- io.ReadWriter
- io.ByteWriter
- stringWriter
- runeWriter
- truncater
- grower
- bytesReader
- lener
-}
-
-// A Buffer is a variable-sized buffer of bytes with Read and Write methods.
-// The zero value for Buffer is an empty buffer ready to use.
-type Buffer struct {
- buf []byte // contents are the bytes buf[off : len(buf)]
- off int // read at &buf[off], write at &buf[len(buf)]
- runeBytes [utf8.UTFMax]byte // avoid allocation of slice on each WriteByte or Rune
- encoder *json.Encoder
-}
-
-// ErrTooLarge is passed to panic if memory cannot be allocated to store data in a buffer.
-var ErrTooLarge = errors.New("fflib.v1.Buffer: too large")
-
-// Bytes returns a slice of the contents of the unread portion of the buffer;
-// len(b.Bytes()) == b.Len(). If the caller changes the contents of the
-// returned slice, the contents of the buffer will change provided there
-// are no intervening method calls on the Buffer.
-func (b *Buffer) Bytes() []byte { return b.buf[b.off:] }
-
-// String returns the contents of the unread portion of the buffer
-// as a string. If the Buffer is a nil pointer, it returns "".
-func (b *Buffer) String() string {
- if b == nil {
- // Special case, useful in debugging.
- return ""
- }
- return string(b.buf[b.off:])
-}
-
-// Len returns the number of bytes of the unread portion of the buffer;
-// b.Len() == len(b.Bytes()).
-func (b *Buffer) Len() int { return len(b.buf) - b.off }
-
-// Truncate discards all but the first n unread bytes from the buffer.
-// It panics if n is negative or greater than the length of the buffer.
-func (b *Buffer) Truncate(n int) {
- if n == 0 {
- b.off = 0
- b.buf = b.buf[0:0]
- } else {
- b.buf = b.buf[0 : b.off+n]
- }
-}
-
-// Reset resets the buffer so it has no content.
-// b.Reset() is the same as b.Truncate(0).
-func (b *Buffer) Reset() { b.Truncate(0) }
-
-// grow grows the buffer to guarantee space for n more bytes.
-// It returns the index where bytes should be written.
-// If the buffer can't grow it will panic with ErrTooLarge.
-func (b *Buffer) grow(n int) int {
- // If we have no buffer, get one from the pool
- m := b.Len()
- if m == 0 {
- if b.buf == nil {
- b.buf = makeSlice(2 * n)
- b.off = 0
- } else if b.off != 0 {
- // If buffer is empty, reset to recover space.
- b.Truncate(0)
- }
- }
- if len(b.buf)+n > cap(b.buf) {
- var buf []byte
- if m+n <= cap(b.buf)/2 {
- // We can slide things down instead of allocating a new
- // slice. We only need m+n <= cap(b.buf) to slide, but
- // we instead let capacity get twice as large so we
- // don't spend all our time copying.
- copy(b.buf[:], b.buf[b.off:])
- buf = b.buf[:m]
- } else {
- // not enough space anywhere
- buf = makeSlice(2*cap(b.buf) + n)
- copy(buf, b.buf[b.off:])
- }
- Pool(b.buf)
- b.buf = buf
- b.off = 0
- }
- b.buf = b.buf[0 : b.off+m+n]
- return b.off + m
-}
-
-// Grow grows the buffer's capacity, if necessary, to guarantee space for
-// another n bytes. After Grow(n), at least n bytes can be written to the
-// buffer without another allocation.
-// If n is negative, Grow will panic.
-// If the buffer can't grow it will panic with ErrTooLarge.
-func (b *Buffer) Grow(n int) {
- if n < 0 {
- panic("bytes.Buffer.Grow: negative count")
- }
- m := b.grow(n)
- b.buf = b.buf[0:m]
-}
-
-// Write appends the contents of p to the buffer, growing the buffer as
-// needed. The return value n is the length of p; err is always nil. If the
-// buffer becomes too large, Write will panic with ErrTooLarge.
-func (b *Buffer) Write(p []byte) (n int, err error) {
- m := b.grow(len(p))
- return copy(b.buf[m:], p), nil
-}
-
-// WriteString appends the contents of s to the buffer, growing the buffer as
-// needed. The return value n is the length of s; err is always nil. If the
-// buffer becomes too large, WriteString will panic with ErrTooLarge.
-func (b *Buffer) WriteString(s string) (n int, err error) {
- m := b.grow(len(s))
- return copy(b.buf[m:], s), nil
-}
-
-// MinRead is the minimum slice size passed to a Read call by
-// Buffer.ReadFrom. As long as the Buffer has at least MinRead bytes beyond
-// what is required to hold the contents of r, ReadFrom will not grow the
-// underlying buffer.
-const minRead = 512
-
-// ReadFrom reads data from r until EOF and appends it to the buffer, growing
-// the buffer as needed. The return value n is the number of bytes read. Any
-// error except io.EOF encountered during the read is also returned. If the
-// buffer becomes too large, ReadFrom will panic with ErrTooLarge.
-func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) {
- // If buffer is empty, reset to recover space.
- if b.off >= len(b.buf) {
- b.Truncate(0)
- }
- for {
- if free := cap(b.buf) - len(b.buf); free < minRead {
- // not enough space at end
- newBuf := b.buf
- if b.off+free < minRead {
- // not enough space using beginning of buffer;
- // double buffer capacity
- newBuf = makeSlice(2*cap(b.buf) + minRead)
- }
- copy(newBuf, b.buf[b.off:])
- Pool(b.buf)
- b.buf = newBuf[:len(b.buf)-b.off]
- b.off = 0
- }
- m, e := r.Read(b.buf[len(b.buf):cap(b.buf)])
- b.buf = b.buf[0 : len(b.buf)+m]
- n += int64(m)
- if e == io.EOF {
- break
- }
- if e != nil {
- return n, e
- }
- }
- return n, nil // err is EOF, so return nil explicitly
-}
-
-// WriteTo writes data to w until the buffer is drained or an error occurs.
-// The return value n is the number of bytes written; it always fits into an
-// int, but it is int64 to match the io.WriterTo interface. Any error
-// encountered during the write is also returned.
-func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) {
- if b.off < len(b.buf) {
- nBytes := b.Len()
- m, e := w.Write(b.buf[b.off:])
- if m > nBytes {
- panic("bytes.Buffer.WriteTo: invalid Write count")
- }
- b.off += m
- n = int64(m)
- if e != nil {
- return n, e
- }
- // all bytes should have been written, by definition of
- // Write method in io.Writer
- if m != nBytes {
- return n, io.ErrShortWrite
- }
- }
- // Buffer is now empty; reset.
- b.Truncate(0)
- return
-}
-
-// WriteByte appends the byte c to the buffer, growing the buffer as needed.
-// The returned error is always nil, but is included to match bufio.Writer's
-// WriteByte. If the buffer becomes too large, WriteByte will panic with
-// ErrTooLarge.
-func (b *Buffer) WriteByte(c byte) error {
- m := b.grow(1)
- b.buf[m] = c
- return nil
-}
-
-func (b *Buffer) Rewind(n int) error {
- b.buf = b.buf[:len(b.buf)-n]
- return nil
-}
-
-func (b *Buffer) Encode(v interface{}) error {
- if b.encoder == nil {
- b.encoder = json.NewEncoder(b)
- }
- return b.encoder.Encode(v)
-}
-
-// WriteRune appends the UTF-8 encoding of Unicode code point r to the
-// buffer, returning its length and an error, which is always nil but is
-// included to match bufio.Writer's WriteRune. The buffer is grown as needed;
-// if it becomes too large, WriteRune will panic with ErrTooLarge.
-func (b *Buffer) WriteRune(r rune) (n int, err error) {
- if r < utf8.RuneSelf {
- b.WriteByte(byte(r))
- return 1, nil
- }
- n = utf8.EncodeRune(b.runeBytes[0:], r)
- b.Write(b.runeBytes[0:n])
- return n, nil
-}
-
-// Read reads the next len(p) bytes from the buffer or until the buffer
-// is drained. The return value n is the number of bytes read. If the
-// buffer has no data to return, err is io.EOF (unless len(p) is zero);
-// otherwise it is nil.
-func (b *Buffer) Read(p []byte) (n int, err error) {
- if b.off >= len(b.buf) {
- // Buffer is empty, reset to recover space.
- b.Truncate(0)
- if len(p) == 0 {
- return
- }
- return 0, io.EOF
- }
- n = copy(p, b.buf[b.off:])
- b.off += n
- return
-}
-
-// Next returns a slice containing the next n bytes from the buffer,
-// advancing the buffer as if the bytes had been returned by Read.
-// If there are fewer than n bytes in the buffer, Next returns the entire buffer.
-// The slice is only valid until the next call to a read or write method.
-func (b *Buffer) Next(n int) []byte {
- m := b.Len()
- if n > m {
- n = m
- }
- data := b.buf[b.off : b.off+n]
- b.off += n
- return data
-}
-
-// ReadByte reads and returns the next byte from the buffer.
-// If no byte is available, it returns error io.EOF.
-func (b *Buffer) ReadByte() (c byte, err error) {
- if b.off >= len(b.buf) {
- // Buffer is empty, reset to recover space.
- b.Truncate(0)
- return 0, io.EOF
- }
- c = b.buf[b.off]
- b.off++
- return c, nil
-}
-
-// ReadRune reads and returns the next UTF-8-encoded
-// Unicode code point from the buffer.
-// If no bytes are available, the error returned is io.EOF.
-// If the bytes are an erroneous UTF-8 encoding, it
-// consumes one byte and returns U+FFFD, 1.
-func (b *Buffer) ReadRune() (r rune, size int, err error) {
- if b.off >= len(b.buf) {
- // Buffer is empty, reset to recover space.
- b.Truncate(0)
- return 0, 0, io.EOF
- }
- c := b.buf[b.off]
- if c < utf8.RuneSelf {
- b.off++
- return rune(c), 1, nil
- }
- r, n := utf8.DecodeRune(b.buf[b.off:])
- b.off += n
- return r, n, nil
-}
-
-// ReadBytes reads until the first occurrence of delim in the input,
-// returning a slice containing the data up to and including the delimiter.
-// If ReadBytes encounters an error before finding a delimiter,
-// it returns the data read before the error and the error itself (often io.EOF).
-// ReadBytes returns err != nil if and only if the returned data does not end in
-// delim.
-func (b *Buffer) ReadBytes(delim byte) (line []byte, err error) {
- slice, err := b.readSlice(delim)
- // return a copy of slice. The buffer's backing array may
- // be overwritten by later calls.
- line = append(line, slice...)
- return
-}
-
-// readSlice is like ReadBytes but returns a reference to internal buffer data.
-func (b *Buffer) readSlice(delim byte) (line []byte, err error) {
- i := bytes.IndexByte(b.buf[b.off:], delim)
- end := b.off + i + 1
- if i < 0 {
- end = len(b.buf)
- err = io.EOF
- }
- line = b.buf[b.off:end]
- b.off = end
- return line, err
-}
-
-// ReadString reads until the first occurrence of delim in the input,
-// returning a string containing the data up to and including the delimiter.
-// If ReadString encounters an error before finding a delimiter,
-// it returns the data read before the error and the error itself (often io.EOF).
-// ReadString returns err != nil if and only if the returned data does not end
-// in delim.
-func (b *Buffer) ReadString(delim byte) (line string, err error) {
- slice, err := b.readSlice(delim)
- return string(slice), err
-}
-
-// NewBuffer creates and initializes a new Buffer using buf as its initial
-// contents. It is intended to prepare a Buffer to read existing data. It
-// can also be used to size the internal buffer for writing. To do that,
-// buf should have the desired capacity but a length of zero.
-//
-// In most cases, new(Buffer) (or just declaring a Buffer variable) is
-// sufficient to initialize a Buffer.
-func NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} }
-
-// NewBufferString creates and initializes a new Buffer using string s as its
-// initial contents. It is intended to prepare a buffer to read an existing
-// string.
-//
-// In most cases, new(Buffer) (or just declaring a Buffer variable) is
-// sufficient to initialize a Buffer.
-func NewBufferString(s string) *Buffer {
- return &Buffer{buf: []byte(s)}
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/buffer_nopool.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/buffer_nopool.go
deleted file mode 100644
index b84af6ff..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/buffer_nopool.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// +build !go1.3
-
-package v1
-
-// Stub version of buffer_pool.go for Go 1.2, which doesn't have sync.Pool.
-
-func Pool(b []byte) {}
-
-func makeSlice(n int) []byte {
- return make([]byte, n)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/buffer_pool.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/buffer_pool.go
deleted file mode 100644
index a021c57c..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/buffer_pool.go
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.3
-
-package v1
-
-// Allocation pools for Buffers.
-
-import "sync"
-
-var pools [14]sync.Pool
-var pool64 *sync.Pool
-
-func init() {
- var i uint
- // TODO(pquerna): add science here around actual pool sizes.
- for i = 6; i < 20; i++ {
- n := 1 << i
- pools[poolNum(n)].New = func() interface{} { return make([]byte, 0, n) }
- }
- pool64 = &pools[0]
-}
-
-// This returns the pool number that will give a buffer of
-// at least 'i' bytes.
-func poolNum(i int) int {
- // TODO(pquerna): convert to log2 w/ bsr asm instruction:
- //
- if i <= 64 {
- return 0
- } else if i <= 128 {
- return 1
- } else if i <= 256 {
- return 2
- } else if i <= 512 {
- return 3
- } else if i <= 1024 {
- return 4
- } else if i <= 2048 {
- return 5
- } else if i <= 4096 {
- return 6
- } else if i <= 8192 {
- return 7
- } else if i <= 16384 {
- return 8
- } else if i <= 32768 {
- return 9
- } else if i <= 65536 {
- return 10
- } else if i <= 131072 {
- return 11
- } else if i <= 262144 {
- return 12
- } else if i <= 524288 {
- return 13
- } else {
- return -1
- }
-}
-
-// Send a buffer to the Pool to reuse for other instances.
-// You may no longer utilize the content of the buffer, since it may be used
-// by other goroutines.
-func Pool(b []byte) {
- if b == nil {
- return
- }
- c := cap(b)
-
- // Our smallest buffer is 64 bytes, so we discard smaller buffers.
- if c < 64 {
- return
- }
-
- // We need to put the incoming buffer into the NEXT buffer,
- // since a buffer guarantees AT LEAST the number of bytes available
- // that is the top of this buffer.
- // That is the reason for dividing the cap by 2, so it gets into the NEXT bucket.
- // We add 2 to avoid rounding down if size is exactly power of 2.
- pn := poolNum((c + 2) >> 1)
- if pn != -1 {
- pools[pn].Put(b[0:0])
- }
- // if we didn't have a slot for this []byte, we just drop it and let the GC
- // take care of it.
-}
-
-// makeSlice allocates a slice of size n -- it will attempt to use a pool'ed
-// instance whenever possible.
-func makeSlice(n int) []byte {
- if n <= 64 {
- return pool64.Get().([]byte)[0:n]
- }
-
- pn := poolNum(n)
-
- if pn != -1 {
- return pools[pn].Get().([]byte)[0:n]
- } else {
- return make([]byte, n)
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/bytenum.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/bytenum.go
deleted file mode 100644
index 08477409..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/bytenum.go
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * Copyright 2014 Paul Querna
- *
- * 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.
- *
- */
-
-/* Portions of this file are on Go stdlib's strconv/iota.go */
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package v1
-
-import (
- "github.com/pquerna/ffjson/fflib/v1/internal"
-)
-
-func ParseFloat(s []byte, bitSize int) (f float64, err error) {
- return internal.ParseFloat(s, bitSize)
-}
-
-// ParseUint is like ParseInt but for unsigned numbers, and oeprating on []byte
-func ParseUint(s []byte, base int, bitSize int) (n uint64, err error) {
- if len(s) == 1 {
- switch s[0] {
- case '0':
- return 0, nil
- case '1':
- return 1, nil
- case '2':
- return 2, nil
- case '3':
- return 3, nil
- case '4':
- return 4, nil
- case '5':
- return 5, nil
- case '6':
- return 6, nil
- case '7':
- return 7, nil
- case '8':
- return 8, nil
- case '9':
- return 9, nil
- }
- }
- return internal.ParseUint(s, base, bitSize)
-}
-
-func ParseInt(s []byte, base int, bitSize int) (i int64, err error) {
- if len(s) == 1 {
- switch s[0] {
- case '0':
- return 0, nil
- case '1':
- return 1, nil
- case '2':
- return 2, nil
- case '3':
- return 3, nil
- case '4':
- return 4, nil
- case '5':
- return 5, nil
- case '6':
- return 6, nil
- case '7':
- return 7, nil
- case '8':
- return 8, nil
- case '9':
- return 9, nil
- }
- }
- return internal.ParseInt(s, base, bitSize)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/decimal.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/decimal.go
deleted file mode 100644
index 069df7a0..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/decimal.go
+++ /dev/null
@@ -1,378 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Multiprecision decimal numbers.
-// For floating-point formatting only; not general purpose.
-// Only operations are assign and (binary) left/right shift.
-// Can do binary floating point in multiprecision decimal precisely
-// because 2 divides 10; cannot do decimal floating point
-// in multiprecision binary precisely.
-
-package v1
-
-type decimal struct {
- d [800]byte // digits
- nd int // number of digits used
- dp int // decimal point
- neg bool
- trunc bool // discarded nonzero digits beyond d[:nd]
-}
-
-func (a *decimal) String() string {
- n := 10 + a.nd
- if a.dp > 0 {
- n += a.dp
- }
- if a.dp < 0 {
- n += -a.dp
- }
-
- buf := make([]byte, n)
- w := 0
- switch {
- case a.nd == 0:
- return "0"
-
- case a.dp <= 0:
- // zeros fill space between decimal point and digits
- buf[w] = '0'
- w++
- buf[w] = '.'
- w++
- w += digitZero(buf[w : w+-a.dp])
- w += copy(buf[w:], a.d[0:a.nd])
-
- case a.dp < a.nd:
- // decimal point in middle of digits
- w += copy(buf[w:], a.d[0:a.dp])
- buf[w] = '.'
- w++
- w += copy(buf[w:], a.d[a.dp:a.nd])
-
- default:
- // zeros fill space between digits and decimal point
- w += copy(buf[w:], a.d[0:a.nd])
- w += digitZero(buf[w : w+a.dp-a.nd])
- }
- return string(buf[0:w])
-}
-
-func digitZero(dst []byte) int {
- for i := range dst {
- dst[i] = '0'
- }
- return len(dst)
-}
-
-// trim trailing zeros from number.
-// (They are meaningless; the decimal point is tracked
-// independent of the number of digits.)
-func trim(a *decimal) {
- for a.nd > 0 && a.d[a.nd-1] == '0' {
- a.nd--
- }
- if a.nd == 0 {
- a.dp = 0
- }
-}
-
-// Assign v to a.
-func (a *decimal) Assign(v uint64) {
- var buf [24]byte
-
- // Write reversed decimal in buf.
- n := 0
- for v > 0 {
- v1 := v / 10
- v -= 10 * v1
- buf[n] = byte(v + '0')
- n++
- v = v1
- }
-
- // Reverse again to produce forward decimal in a.d.
- a.nd = 0
- for n--; n >= 0; n-- {
- a.d[a.nd] = buf[n]
- a.nd++
- }
- a.dp = a.nd
- trim(a)
-}
-
-// Maximum shift that we can do in one pass without overflow.
-// Signed int has 31 bits, and we have to be able to accommodate 9<>k == 0; r++ {
- if r >= a.nd {
- if n == 0 {
- // a == 0; shouldn't get here, but handle anyway.
- a.nd = 0
- return
- }
- for n>>k == 0 {
- n = n * 10
- r++
- }
- break
- }
- c := int(a.d[r])
- n = n*10 + c - '0'
- }
- a.dp -= r - 1
-
- // Pick up a digit, put down a digit.
- for ; r < a.nd; r++ {
- c := int(a.d[r])
- dig := n >> k
- n -= dig << k
- a.d[w] = byte(dig + '0')
- w++
- n = n*10 + c - '0'
- }
-
- // Put down extra digits.
- for n > 0 {
- dig := n >> k
- n -= dig << k
- if w < len(a.d) {
- a.d[w] = byte(dig + '0')
- w++
- } else if dig > 0 {
- a.trunc = true
- }
- n = n * 10
- }
-
- a.nd = w
- trim(a)
-}
-
-// Cheat sheet for left shift: table indexed by shift count giving
-// number of new digits that will be introduced by that shift.
-//
-// For example, leftcheats[4] = {2, "625"}. That means that
-// if we are shifting by 4 (multiplying by 16), it will add 2 digits
-// when the string prefix is "625" through "999", and one fewer digit
-// if the string prefix is "000" through "624".
-//
-// Credit for this trick goes to Ken.
-
-type leftCheat struct {
- delta int // number of new digits
- cutoff string // minus one digit if original < a.
-}
-
-var leftcheats = []leftCheat{
- // Leading digits of 1/2^i = 5^i.
- // 5^23 is not an exact 64-bit floating point number,
- // so have to use bc for the math.
- /*
- seq 27 | sed 's/^/5^/' | bc |
- awk 'BEGIN{ print "\tleftCheat{ 0, \"\" }," }
- {
- log2 = log(2)/log(10)
- printf("\tleftCheat{ %d, \"%s\" },\t// * %d\n",
- int(log2*NR+1), $0, 2**NR)
- }'
- */
- {0, ""},
- {1, "5"}, // * 2
- {1, "25"}, // * 4
- {1, "125"}, // * 8
- {2, "625"}, // * 16
- {2, "3125"}, // * 32
- {2, "15625"}, // * 64
- {3, "78125"}, // * 128
- {3, "390625"}, // * 256
- {3, "1953125"}, // * 512
- {4, "9765625"}, // * 1024
- {4, "48828125"}, // * 2048
- {4, "244140625"}, // * 4096
- {4, "1220703125"}, // * 8192
- {5, "6103515625"}, // * 16384
- {5, "30517578125"}, // * 32768
- {5, "152587890625"}, // * 65536
- {6, "762939453125"}, // * 131072
- {6, "3814697265625"}, // * 262144
- {6, "19073486328125"}, // * 524288
- {7, "95367431640625"}, // * 1048576
- {7, "476837158203125"}, // * 2097152
- {7, "2384185791015625"}, // * 4194304
- {7, "11920928955078125"}, // * 8388608
- {8, "59604644775390625"}, // * 16777216
- {8, "298023223876953125"}, // * 33554432
- {8, "1490116119384765625"}, // * 67108864
- {9, "7450580596923828125"}, // * 134217728
-}
-
-// Is the leading prefix of b lexicographically less than s?
-func prefixIsLessThan(b []byte, s string) bool {
- for i := 0; i < len(s); i++ {
- if i >= len(b) {
- return true
- }
- if b[i] != s[i] {
- return b[i] < s[i]
- }
- }
- return false
-}
-
-// Binary shift left (/ 2) by k bits. k <= maxShift to avoid overflow.
-func leftShift(a *decimal, k uint) {
- delta := leftcheats[k].delta
- if prefixIsLessThan(a.d[0:a.nd], leftcheats[k].cutoff) {
- delta--
- }
-
- r := a.nd // read index
- w := a.nd + delta // write index
- n := 0
-
- // Pick up a digit, put down a digit.
- for r--; r >= 0; r-- {
- n += (int(a.d[r]) - '0') << k
- quo := n / 10
- rem := n - 10*quo
- w--
- if w < len(a.d) {
- a.d[w] = byte(rem + '0')
- } else if rem != 0 {
- a.trunc = true
- }
- n = quo
- }
-
- // Put down extra digits.
- for n > 0 {
- quo := n / 10
- rem := n - 10*quo
- w--
- if w < len(a.d) {
- a.d[w] = byte(rem + '0')
- } else if rem != 0 {
- a.trunc = true
- }
- n = quo
- }
-
- a.nd += delta
- if a.nd >= len(a.d) {
- a.nd = len(a.d)
- }
- a.dp += delta
- trim(a)
-}
-
-// Binary shift left (k > 0) or right (k < 0).
-func (a *decimal) Shift(k int) {
- switch {
- case a.nd == 0:
- // nothing to do: a == 0
- case k > 0:
- for k > maxShift {
- leftShift(a, maxShift)
- k -= maxShift
- }
- leftShift(a, uint(k))
- case k < 0:
- for k < -maxShift {
- rightShift(a, maxShift)
- k += maxShift
- }
- rightShift(a, uint(-k))
- }
-}
-
-// If we chop a at nd digits, should we round up?
-func shouldRoundUp(a *decimal, nd int) bool {
- if nd < 0 || nd >= a.nd {
- return false
- }
- if a.d[nd] == '5' && nd+1 == a.nd { // exactly halfway - round to even
- // if we truncated, a little higher than what's recorded - always round up
- if a.trunc {
- return true
- }
- return nd > 0 && (a.d[nd-1]-'0')%2 != 0
- }
- // not halfway - digit tells all
- return a.d[nd] >= '5'
-}
-
-// Round a to nd digits (or fewer).
-// If nd is zero, it means we're rounding
-// just to the left of the digits, as in
-// 0.09 -> 0.1.
-func (a *decimal) Round(nd int) {
- if nd < 0 || nd >= a.nd {
- return
- }
- if shouldRoundUp(a, nd) {
- a.RoundUp(nd)
- } else {
- a.RoundDown(nd)
- }
-}
-
-// Round a down to nd digits (or fewer).
-func (a *decimal) RoundDown(nd int) {
- if nd < 0 || nd >= a.nd {
- return
- }
- a.nd = nd
- trim(a)
-}
-
-// Round a up to nd digits (or fewer).
-func (a *decimal) RoundUp(nd int) {
- if nd < 0 || nd >= a.nd {
- return
- }
-
- // round up
- for i := nd - 1; i >= 0; i-- {
- c := a.d[i]
- if c < '9' { // can stop after this digit
- a.d[i]++
- a.nd = i + 1
- return
- }
- }
-
- // Number is all 9s.
- // Change to single 1 with adjusted decimal point.
- a.d[0] = '1'
- a.nd = 1
- a.dp++
-}
-
-// Extract integer part, rounded appropriately.
-// No guarantees about overflow.
-func (a *decimal) RoundedInteger() uint64 {
- if a.dp > 20 {
- return 0xFFFFFFFFFFFFFFFF
- }
- var i int
- n := uint64(0)
- for i = 0; i < a.dp && i < a.nd; i++ {
- n = n*10 + uint64(a.d[i]-'0')
- }
- for ; i < a.dp; i++ {
- n *= 10
- }
- if shouldRoundUp(a, a.dp) {
- n++
- }
- return n
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/extfloat.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/extfloat.go
deleted file mode 100644
index 508ddc6b..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/extfloat.go
+++ /dev/null
@@ -1,668 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package v1
-
-// An extFloat represents an extended floating-point number, with more
-// precision than a float64. It does not try to save bits: the
-// number represented by the structure is mant*(2^exp), with a negative
-// sign if neg is true.
-type extFloat struct {
- mant uint64
- exp int
- neg bool
-}
-
-// Powers of ten taken from double-conversion library.
-// http://code.google.com/p/double-conversion/
-const (
- firstPowerOfTen = -348
- stepPowerOfTen = 8
-)
-
-var smallPowersOfTen = [...]extFloat{
- {1 << 63, -63, false}, // 1
- {0xa << 60, -60, false}, // 1e1
- {0x64 << 57, -57, false}, // 1e2
- {0x3e8 << 54, -54, false}, // 1e3
- {0x2710 << 50, -50, false}, // 1e4
- {0x186a0 << 47, -47, false}, // 1e5
- {0xf4240 << 44, -44, false}, // 1e6
- {0x989680 << 40, -40, false}, // 1e7
-}
-
-var powersOfTen = [...]extFloat{
- {0xfa8fd5a0081c0288, -1220, false}, // 10^-348
- {0xbaaee17fa23ebf76, -1193, false}, // 10^-340
- {0x8b16fb203055ac76, -1166, false}, // 10^-332
- {0xcf42894a5dce35ea, -1140, false}, // 10^-324
- {0x9a6bb0aa55653b2d, -1113, false}, // 10^-316
- {0xe61acf033d1a45df, -1087, false}, // 10^-308
- {0xab70fe17c79ac6ca, -1060, false}, // 10^-300
- {0xff77b1fcbebcdc4f, -1034, false}, // 10^-292
- {0xbe5691ef416bd60c, -1007, false}, // 10^-284
- {0x8dd01fad907ffc3c, -980, false}, // 10^-276
- {0xd3515c2831559a83, -954, false}, // 10^-268
- {0x9d71ac8fada6c9b5, -927, false}, // 10^-260
- {0xea9c227723ee8bcb, -901, false}, // 10^-252
- {0xaecc49914078536d, -874, false}, // 10^-244
- {0x823c12795db6ce57, -847, false}, // 10^-236
- {0xc21094364dfb5637, -821, false}, // 10^-228
- {0x9096ea6f3848984f, -794, false}, // 10^-220
- {0xd77485cb25823ac7, -768, false}, // 10^-212
- {0xa086cfcd97bf97f4, -741, false}, // 10^-204
- {0xef340a98172aace5, -715, false}, // 10^-196
- {0xb23867fb2a35b28e, -688, false}, // 10^-188
- {0x84c8d4dfd2c63f3b, -661, false}, // 10^-180
- {0xc5dd44271ad3cdba, -635, false}, // 10^-172
- {0x936b9fcebb25c996, -608, false}, // 10^-164
- {0xdbac6c247d62a584, -582, false}, // 10^-156
- {0xa3ab66580d5fdaf6, -555, false}, // 10^-148
- {0xf3e2f893dec3f126, -529, false}, // 10^-140
- {0xb5b5ada8aaff80b8, -502, false}, // 10^-132
- {0x87625f056c7c4a8b, -475, false}, // 10^-124
- {0xc9bcff6034c13053, -449, false}, // 10^-116
- {0x964e858c91ba2655, -422, false}, // 10^-108
- {0xdff9772470297ebd, -396, false}, // 10^-100
- {0xa6dfbd9fb8e5b88f, -369, false}, // 10^-92
- {0xf8a95fcf88747d94, -343, false}, // 10^-84
- {0xb94470938fa89bcf, -316, false}, // 10^-76
- {0x8a08f0f8bf0f156b, -289, false}, // 10^-68
- {0xcdb02555653131b6, -263, false}, // 10^-60
- {0x993fe2c6d07b7fac, -236, false}, // 10^-52
- {0xe45c10c42a2b3b06, -210, false}, // 10^-44
- {0xaa242499697392d3, -183, false}, // 10^-36
- {0xfd87b5f28300ca0e, -157, false}, // 10^-28
- {0xbce5086492111aeb, -130, false}, // 10^-20
- {0x8cbccc096f5088cc, -103, false}, // 10^-12
- {0xd1b71758e219652c, -77, false}, // 10^-4
- {0x9c40000000000000, -50, false}, // 10^4
- {0xe8d4a51000000000, -24, false}, // 10^12
- {0xad78ebc5ac620000, 3, false}, // 10^20
- {0x813f3978f8940984, 30, false}, // 10^28
- {0xc097ce7bc90715b3, 56, false}, // 10^36
- {0x8f7e32ce7bea5c70, 83, false}, // 10^44
- {0xd5d238a4abe98068, 109, false}, // 10^52
- {0x9f4f2726179a2245, 136, false}, // 10^60
- {0xed63a231d4c4fb27, 162, false}, // 10^68
- {0xb0de65388cc8ada8, 189, false}, // 10^76
- {0x83c7088e1aab65db, 216, false}, // 10^84
- {0xc45d1df942711d9a, 242, false}, // 10^92
- {0x924d692ca61be758, 269, false}, // 10^100
- {0xda01ee641a708dea, 295, false}, // 10^108
- {0xa26da3999aef774a, 322, false}, // 10^116
- {0xf209787bb47d6b85, 348, false}, // 10^124
- {0xb454e4a179dd1877, 375, false}, // 10^132
- {0x865b86925b9bc5c2, 402, false}, // 10^140
- {0xc83553c5c8965d3d, 428, false}, // 10^148
- {0x952ab45cfa97a0b3, 455, false}, // 10^156
- {0xde469fbd99a05fe3, 481, false}, // 10^164
- {0xa59bc234db398c25, 508, false}, // 10^172
- {0xf6c69a72a3989f5c, 534, false}, // 10^180
- {0xb7dcbf5354e9bece, 561, false}, // 10^188
- {0x88fcf317f22241e2, 588, false}, // 10^196
- {0xcc20ce9bd35c78a5, 614, false}, // 10^204
- {0x98165af37b2153df, 641, false}, // 10^212
- {0xe2a0b5dc971f303a, 667, false}, // 10^220
- {0xa8d9d1535ce3b396, 694, false}, // 10^228
- {0xfb9b7cd9a4a7443c, 720, false}, // 10^236
- {0xbb764c4ca7a44410, 747, false}, // 10^244
- {0x8bab8eefb6409c1a, 774, false}, // 10^252
- {0xd01fef10a657842c, 800, false}, // 10^260
- {0x9b10a4e5e9913129, 827, false}, // 10^268
- {0xe7109bfba19c0c9d, 853, false}, // 10^276
- {0xac2820d9623bf429, 880, false}, // 10^284
- {0x80444b5e7aa7cf85, 907, false}, // 10^292
- {0xbf21e44003acdd2d, 933, false}, // 10^300
- {0x8e679c2f5e44ff8f, 960, false}, // 10^308
- {0xd433179d9c8cb841, 986, false}, // 10^316
- {0x9e19db92b4e31ba9, 1013, false}, // 10^324
- {0xeb96bf6ebadf77d9, 1039, false}, // 10^332
- {0xaf87023b9bf0ee6b, 1066, false}, // 10^340
-}
-
-// floatBits returns the bits of the float64 that best approximates
-// the extFloat passed as receiver. Overflow is set to true if
-// the resulting float64 is ±Inf.
-func (f *extFloat) floatBits(flt *floatInfo) (bits uint64, overflow bool) {
- f.Normalize()
-
- exp := f.exp + 63
-
- // Exponent too small.
- if exp < flt.bias+1 {
- n := flt.bias + 1 - exp
- f.mant >>= uint(n)
- exp += n
- }
-
- // Extract 1+flt.mantbits bits from the 64-bit mantissa.
- mant := f.mant >> (63 - flt.mantbits)
- if f.mant&(1<<(62-flt.mantbits)) != 0 {
- // Round up.
- mant += 1
- }
-
- // Rounding might have added a bit; shift down.
- if mant == 2<>= 1
- exp++
- }
-
- // Infinities.
- if exp-flt.bias >= 1<>uint(-f.exp))<>= uint(-f.exp)
- f.exp = 0
- return *f, *f
- }
- expBiased := exp - flt.bias
-
- upper = extFloat{mant: 2*f.mant + 1, exp: f.exp - 1, neg: f.neg}
- if mant != 1<>(64-32) == 0 {
- mant <<= 32
- exp -= 32
- }
- if mant>>(64-16) == 0 {
- mant <<= 16
- exp -= 16
- }
- if mant>>(64-8) == 0 {
- mant <<= 8
- exp -= 8
- }
- if mant>>(64-4) == 0 {
- mant <<= 4
- exp -= 4
- }
- if mant>>(64-2) == 0 {
- mant <<= 2
- exp -= 2
- }
- if mant>>(64-1) == 0 {
- mant <<= 1
- exp -= 1
- }
- shift = uint(f.exp - exp)
- f.mant, f.exp = mant, exp
- return
-}
-
-// Multiply sets f to the product f*g: the result is correctly rounded,
-// but not normalized.
-func (f *extFloat) Multiply(g extFloat) {
- fhi, flo := f.mant>>32, uint64(uint32(f.mant))
- ghi, glo := g.mant>>32, uint64(uint32(g.mant))
-
- // Cross products.
- cross1 := fhi * glo
- cross2 := flo * ghi
-
- // f.mant*g.mant is fhi*ghi << 64 + (cross1+cross2) << 32 + flo*glo
- f.mant = fhi*ghi + (cross1 >> 32) + (cross2 >> 32)
- rem := uint64(uint32(cross1)) + uint64(uint32(cross2)) + ((flo * glo) >> 32)
- // Round up.
- rem += (1 << 31)
-
- f.mant += (rem >> 32)
- f.exp = f.exp + g.exp + 64
-}
-
-var uint64pow10 = [...]uint64{
- 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
- 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
-}
-
-// AssignDecimal sets f to an approximate value mantissa*10^exp. It
-// returns true if the value represented by f is guaranteed to be the
-// best approximation of d after being rounded to a float64 or
-// float32 depending on flt.
-func (f *extFloat) AssignDecimal(mantissa uint64, exp10 int, neg bool, trunc bool, flt *floatInfo) (ok bool) {
- const uint64digits = 19
- const errorscale = 8
- errors := 0 // An upper bound for error, computed in errorscale*ulp.
- if trunc {
- // the decimal number was truncated.
- errors += errorscale / 2
- }
-
- f.mant = mantissa
- f.exp = 0
- f.neg = neg
-
- // Multiply by powers of ten.
- i := (exp10 - firstPowerOfTen) / stepPowerOfTen
- if exp10 < firstPowerOfTen || i >= len(powersOfTen) {
- return false
- }
- adjExp := (exp10 - firstPowerOfTen) % stepPowerOfTen
-
- // We multiply by exp%step
- if adjExp < uint64digits && mantissa < uint64pow10[uint64digits-adjExp] {
- // We can multiply the mantissa exactly.
- f.mant *= uint64pow10[adjExp]
- f.Normalize()
- } else {
- f.Normalize()
- f.Multiply(smallPowersOfTen[adjExp])
- errors += errorscale / 2
- }
-
- // We multiply by 10 to the exp - exp%step.
- f.Multiply(powersOfTen[i])
- if errors > 0 {
- errors += 1
- }
- errors += errorscale / 2
-
- // Normalize
- shift := f.Normalize()
- errors <<= shift
-
- // Now f is a good approximation of the decimal.
- // Check whether the error is too large: that is, if the mantissa
- // is perturbated by the error, the resulting float64 will change.
- // The 64 bits mantissa is 1 + 52 bits for float64 + 11 extra bits.
- //
- // In many cases the approximation will be good enough.
- denormalExp := flt.bias - 63
- var extrabits uint
- if f.exp <= denormalExp {
- // f.mant * 2^f.exp is smaller than 2^(flt.bias+1).
- extrabits = uint(63 - flt.mantbits + 1 + uint(denormalExp-f.exp))
- } else {
- extrabits = uint(63 - flt.mantbits)
- }
-
- halfway := uint64(1) << (extrabits - 1)
- mant_extra := f.mant & (1< expMax:
- i--
- default:
- break Loop
- }
- }
- // Apply the desired decimal shift on f. It will have exponent
- // in the desired range. This is multiplication by 10^-exp10.
- f.Multiply(powersOfTen[i])
-
- return -(firstPowerOfTen + i*stepPowerOfTen), i
-}
-
-// frexp10Many applies a common shift by a power of ten to a, b, c.
-func frexp10Many(a, b, c *extFloat) (exp10 int) {
- exp10, i := c.frexp10()
- a.Multiply(powersOfTen[i])
- b.Multiply(powersOfTen[i])
- return
-}
-
-// FixedDecimal stores in d the first n significant digits
-// of the decimal representation of f. It returns false
-// if it cannot be sure of the answer.
-func (f *extFloat) FixedDecimal(d *decimalSlice, n int) bool {
- if f.mant == 0 {
- d.nd = 0
- d.dp = 0
- d.neg = f.neg
- return true
- }
- if n == 0 {
- panic("strconv: internal error: extFloat.FixedDecimal called with n == 0")
- }
- // Multiply by an appropriate power of ten to have a reasonable
- // number to process.
- f.Normalize()
- exp10, _ := f.frexp10()
-
- shift := uint(-f.exp)
- integer := uint32(f.mant >> shift)
- fraction := f.mant - (uint64(integer) << shift)
- ε := uint64(1) // ε is the uncertainty we have on the mantissa of f.
-
- // Write exactly n digits to d.
- needed := n // how many digits are left to write.
- integerDigits := 0 // the number of decimal digits of integer.
- pow10 := uint64(1) // the power of ten by which f was scaled.
- for i, pow := 0, uint64(1); i < 20; i++ {
- if pow > uint64(integer) {
- integerDigits = i
- break
- }
- pow *= 10
- }
- rest := integer
- if integerDigits > needed {
- // the integral part is already large, trim the last digits.
- pow10 = uint64pow10[integerDigits-needed]
- integer /= uint32(pow10)
- rest -= integer * uint32(pow10)
- } else {
- rest = 0
- }
-
- // Write the digits of integer: the digits of rest are omitted.
- var buf [32]byte
- pos := len(buf)
- for v := integer; v > 0; {
- v1 := v / 10
- v -= 10 * v1
- pos--
- buf[pos] = byte(v + '0')
- v = v1
- }
- for i := pos; i < len(buf); i++ {
- d.d[i-pos] = buf[i]
- }
- nd := len(buf) - pos
- d.nd = nd
- d.dp = integerDigits + exp10
- needed -= nd
-
- if needed > 0 {
- if rest != 0 || pow10 != 1 {
- panic("strconv: internal error, rest != 0 but needed > 0")
- }
- // Emit digits for the fractional part. Each time, 10*fraction
- // fits in a uint64 without overflow.
- for needed > 0 {
- fraction *= 10
- ε *= 10 // the uncertainty scales as we multiply by ten.
- if 2*ε > 1<> shift
- d.d[nd] = byte(digit + '0')
- fraction -= digit << shift
- nd++
- needed--
- }
- d.nd = nd
- }
-
- // We have written a truncation of f (a numerator / 10^d.dp). The remaining part
- // can be interpreted as a small number (< 1) to be added to the last digit of the
- // numerator.
- //
- // If rest > 0, the amount is:
- // (rest< 0 guarantees that pow10 << shift does not overflow a uint64.
- //
- // If rest = 0, pow10 == 1 and the amount is
- // fraction / (1 << shift)
- // fraction being known with a ±ε uncertainty.
- //
- // We pass this information to the rounding routine for adjustment.
-
- ok := adjustLastDigitFixed(d, uint64(rest)<= 0; i-- {
- if d.d[i] != '0' {
- d.nd = i + 1
- break
- }
- }
- return true
-}
-
-// adjustLastDigitFixed assumes d contains the representation of the integral part
-// of some number, whose fractional part is num / (den << shift). The numerator
-// num is only known up to an uncertainty of size ε, assumed to be less than
-// (den << shift)/2.
-//
-// It will increase the last digit by one to account for correct rounding, typically
-// when the fractional part is greater than 1/2, and will return false if ε is such
-// that no correct answer can be given.
-func adjustLastDigitFixed(d *decimalSlice, num, den uint64, shift uint, ε uint64) bool {
- if num > den< den< den< (den< den<= 0; i-- {
- if d.d[i] == '9' {
- d.nd--
- } else {
- break
- }
- }
- if i < 0 {
- d.d[0] = '1'
- d.nd = 1
- d.dp++
- } else {
- d.d[i]++
- }
- return true
- }
- return false
-}
-
-// ShortestDecimal stores in d the shortest decimal representation of f
-// which belongs to the open interval (lower, upper), where f is supposed
-// to lie. It returns false whenever the result is unsure. The implementation
-// uses the Grisu3 algorithm.
-func (f *extFloat) ShortestDecimal(d *decimalSlice, lower, upper *extFloat) bool {
- if f.mant == 0 {
- d.nd = 0
- d.dp = 0
- d.neg = f.neg
- return true
- }
- if f.exp == 0 && *lower == *f && *lower == *upper {
- // an exact integer.
- var buf [24]byte
- n := len(buf) - 1
- for v := f.mant; v > 0; {
- v1 := v / 10
- v -= 10 * v1
- buf[n] = byte(v + '0')
- n--
- v = v1
- }
- nd := len(buf) - n - 1
- for i := 0; i < nd; i++ {
- d.d[i] = buf[n+1+i]
- }
- d.nd, d.dp = nd, nd
- for d.nd > 0 && d.d[d.nd-1] == '0' {
- d.nd--
- }
- if d.nd == 0 {
- d.dp = 0
- }
- d.neg = f.neg
- return true
- }
- upper.Normalize()
- // Uniformize exponents.
- if f.exp > upper.exp {
- f.mant <<= uint(f.exp - upper.exp)
- f.exp = upper.exp
- }
- if lower.exp > upper.exp {
- lower.mant <<= uint(lower.exp - upper.exp)
- lower.exp = upper.exp
- }
-
- exp10 := frexp10Many(lower, f, upper)
- // Take a safety margin due to rounding in frexp10Many, but we lose precision.
- upper.mant++
- lower.mant--
-
- // The shortest representation of f is either rounded up or down, but
- // in any case, it is a truncation of upper.
- shift := uint(-upper.exp)
- integer := uint32(upper.mant >> shift)
- fraction := upper.mant - (uint64(integer) << shift)
-
- // How far we can go down from upper until the result is wrong.
- allowance := upper.mant - lower.mant
- // How far we should go to get a very precise result.
- targetDiff := upper.mant - f.mant
-
- // Count integral digits: there are at most 10.
- var integerDigits int
- for i, pow := 0, uint64(1); i < 20; i++ {
- if pow > uint64(integer) {
- integerDigits = i
- break
- }
- pow *= 10
- }
- for i := 0; i < integerDigits; i++ {
- pow := uint64pow10[integerDigits-i-1]
- digit := integer / uint32(pow)
- d.d[i] = byte(digit + '0')
- integer -= digit * uint32(pow)
- // evaluate whether we should stop.
- if currentDiff := uint64(integer)<> shift)
- d.d[d.nd] = byte(digit + '0')
- d.nd++
- fraction -= uint64(digit) << shift
- if fraction < allowance*multiplier {
- // We are in the admissible range. Note that if allowance is about to
- // overflow, that is, allowance > 2^64/10, the condition is automatically
- // true due to the limited range of fraction.
- return adjustLastDigit(d,
- fraction, targetDiff*multiplier, allowance*multiplier,
- 1< maxDiff-ulpBinary {
- // we went too far
- return false
- }
- if d.nd == 1 && d.d[0] == '0' {
- // the number has actually reached zero.
- d.nd = 0
- d.dp = 0
- }
- return true
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/fold.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/fold.go
deleted file mode 100644
index 4d33e6f7..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/fold.go
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * Copyright 2014 Paul Querna
- *
- * 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.
- *
- */
-
-/* Portions of this file are on Go stdlib's encoding/json/fold.go */
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package v1
-
-import (
- "unicode/utf8"
-)
-
-const (
- caseMask = ^byte(0x20) // Mask to ignore case in ASCII.
- kelvin = '\u212a'
- smallLongEss = '\u017f'
-)
-
-// equalFoldRight is a specialization of bytes.EqualFold when s is
-// known to be all ASCII (including punctuation), but contains an 's',
-// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t.
-// See comments on foldFunc.
-func EqualFoldRight(s, t []byte) bool {
- for _, sb := range s {
- if len(t) == 0 {
- return false
- }
- tb := t[0]
- if tb < utf8.RuneSelf {
- if sb != tb {
- sbUpper := sb & caseMask
- if 'A' <= sbUpper && sbUpper <= 'Z' {
- if sbUpper != tb&caseMask {
- return false
- }
- } else {
- return false
- }
- }
- t = t[1:]
- continue
- }
- // sb is ASCII and t is not. t must be either kelvin
- // sign or long s; sb must be s, S, k, or K.
- tr, size := utf8.DecodeRune(t)
- switch sb {
- case 's', 'S':
- if tr != smallLongEss {
- return false
- }
- case 'k', 'K':
- if tr != kelvin {
- return false
- }
- default:
- return false
- }
- t = t[size:]
-
- }
- if len(t) > 0 {
- return false
- }
- return true
-}
-
-// asciiEqualFold is a specialization of bytes.EqualFold for use when
-// s is all ASCII (but may contain non-letters) and contains no
-// special-folding letters.
-// See comments on foldFunc.
-func AsciiEqualFold(s, t []byte) bool {
- if len(s) != len(t) {
- return false
- }
- for i, sb := range s {
- tb := t[i]
- if sb == tb {
- continue
- }
- if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {
- if sb&caseMask != tb&caseMask {
- return false
- }
- } else {
- return false
- }
- }
- return true
-}
-
-// simpleLetterEqualFold is a specialization of bytes.EqualFold for
-// use when s is all ASCII letters (no underscores, etc) and also
-// doesn't contain 'k', 'K', 's', or 'S'.
-// See comments on foldFunc.
-func SimpleLetterEqualFold(s, t []byte) bool {
- if len(s) != len(t) {
- return false
- }
- for i, b := range s {
- if b&caseMask != t[i]&caseMask {
- return false
- }
- }
- return true
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/ftoa.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/ftoa.go
deleted file mode 100644
index 360d6dbc..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/ftoa.go
+++ /dev/null
@@ -1,542 +0,0 @@
-package v1
-
-/**
- * Copyright 2015 Paul Querna, Klaus Post
- *
- * 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.
- *
- */
-
-/* Most of this file are on Go stdlib's strconv/ftoa.go */
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-import "math"
-
-// TODO: move elsewhere?
-type floatInfo struct {
- mantbits uint
- expbits uint
- bias int
-}
-
-var optimize = true // can change for testing
-
-var float32info = floatInfo{23, 8, -127}
-var float64info = floatInfo{52, 11, -1023}
-
-// AppendFloat appends the string form of the floating-point number f,
-// as generated by FormatFloat
-func AppendFloat(dst EncodingBuffer, val float64, fmt byte, prec, bitSize int) {
- var bits uint64
- var flt *floatInfo
- switch bitSize {
- case 32:
- bits = uint64(math.Float32bits(float32(val)))
- flt = &float32info
- case 64:
- bits = math.Float64bits(val)
- flt = &float64info
- default:
- panic("strconv: illegal AppendFloat/FormatFloat bitSize")
- }
-
- neg := bits>>(flt.expbits+flt.mantbits) != 0
- exp := int(bits>>flt.mantbits) & (1< digs.nd && digs.nd >= digs.dp {
- eprec = digs.nd
- }
- // %e is used if the exponent from the conversion
- // is less than -4 or greater than or equal to the precision.
- // if precision was the shortest possible, use precision 6 for this decision.
- if shortest {
- eprec = 6
- }
- exp := digs.dp - 1
- if exp < -4 || exp >= eprec {
- if prec > digs.nd {
- prec = digs.nd
- }
- fmtE(dst, neg, digs, prec-1, fmt+'e'-'g')
- return
- }
- if prec > digs.dp {
- prec = digs.nd
- }
- fmtF(dst, neg, digs, max(prec-digs.dp, 0))
- return
- }
-
- // unknown format
- dst.Write([]byte{'%', fmt})
- return
-}
-
-// Round d (= mant * 2^exp) to the shortest number of digits
-// that will let the original floating point value be precisely
-// reconstructed. Size is original floating point size (64 or 32).
-func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) {
- // If mantissa is zero, the number is zero; stop now.
- if mant == 0 {
- d.nd = 0
- return
- }
-
- // Compute upper and lower such that any decimal number
- // between upper and lower (possibly inclusive)
- // will round to the original floating point number.
-
- // We may see at once that the number is already shortest.
- //
- // Suppose d is not denormal, so that 2^exp <= d < 10^dp.
- // The closest shorter number is at least 10^(dp-nd) away.
- // The lower/upper bounds computed below are at distance
- // at most 2^(exp-mantbits).
- //
- // So the number is already shortest if 10^(dp-nd) > 2^(exp-mantbits),
- // or equivalently log2(10)*(dp-nd) > exp-mantbits.
- // It is true if 332/100*(dp-nd) >= exp-mantbits (log2(10) > 3.32).
- minexp := flt.bias + 1 // minimum possible exponent
- if exp > minexp && 332*(d.dp-d.nd) >= 100*(exp-int(flt.mantbits)) {
- // The number is already shortest.
- return
- }
-
- // d = mant << (exp - mantbits)
- // Next highest floating point number is mant+1 << exp-mantbits.
- // Our upper bound is halfway between, mant*2+1 << exp-mantbits-1.
- upper := new(decimal)
- upper.Assign(mant*2 + 1)
- upper.Shift(exp - int(flt.mantbits) - 1)
-
- // d = mant << (exp - mantbits)
- // Next lowest floating point number is mant-1 << exp-mantbits,
- // unless mant-1 drops the significant bit and exp is not the minimum exp,
- // in which case the next lowest is mant*2-1 << exp-mantbits-1.
- // Either way, call it mantlo << explo-mantbits.
- // Our lower bound is halfway between, mantlo*2+1 << explo-mantbits-1.
- var mantlo uint64
- var explo int
- if mant > 1< 0 {
- dst.WriteByte('.')
- i := 1
- m := min(d.nd, prec+1)
- if i < m {
- dst.Write(d.d[i:m])
- i = m
- }
- for i <= prec {
- dst.WriteByte('0')
- i++
- }
- }
-
- // e±
- dst.WriteByte(fmt)
- exp := d.dp - 1
- if d.nd == 0 { // special case: 0 has exponent 0
- exp = 0
- }
- if exp < 0 {
- ch = '-'
- exp = -exp
- } else {
- ch = '+'
- }
- dst.WriteByte(ch)
-
- // dd or ddd
- switch {
- case exp < 10:
- dst.WriteByte('0')
- dst.WriteByte(byte(exp) + '0')
- case exp < 100:
- dst.WriteByte(byte(exp/10) + '0')
- dst.WriteByte(byte(exp%10) + '0')
- default:
- dst.WriteByte(byte(exp/100) + '0')
- dst.WriteByte(byte(exp/10)%10 + '0')
- dst.WriteByte(byte(exp%10) + '0')
- }
-
- return
-}
-
-// %f: -ddddddd.ddddd
-func fmtF(dst EncodingBuffer, neg bool, d decimalSlice, prec int) {
- // sign
- if neg {
- dst.WriteByte('-')
- }
-
- // integer, padded with zeros as needed.
- if d.dp > 0 {
- m := min(d.nd, d.dp)
- dst.Write(d.d[:m])
- for ; m < d.dp; m++ {
- dst.WriteByte('0')
- }
- } else {
- dst.WriteByte('0')
- }
-
- // fraction
- if prec > 0 {
- dst.WriteByte('.')
- for i := 0; i < prec; i++ {
- ch := byte('0')
- if j := d.dp + i; 0 <= j && j < d.nd {
- ch = d.d[j]
- }
- dst.WriteByte(ch)
- }
- }
-
- return
-}
-
-// %b: -ddddddddp±ddd
-func fmtB(dst EncodingBuffer, neg bool, mant uint64, exp int, flt *floatInfo) {
- // sign
- if neg {
- dst.WriteByte('-')
- }
-
- // mantissa
- formatBits(dst, mant, 10, false)
-
- // p
- dst.WriteByte('p')
-
- // ±exponent
- exp -= int(flt.mantbits)
- if exp >= 0 {
- dst.WriteByte('+')
- }
- formatBits(dst, uint64(exp), 10, exp < 0)
-
- return
-}
-
-func min(a, b int) int {
- if a < b {
- return a
- }
- return b
-}
-
-func max(a, b int) int {
- if a > b {
- return a
- }
- return b
-}
-
-// formatBits computes the string representation of u in the given base.
-// If neg is set, u is treated as negative int64 value.
-func formatBits(dst EncodingBuffer, u uint64, base int, neg bool) {
- if base < 2 || base > len(digits) {
- panic("strconv: illegal AppendInt/FormatInt base")
- }
- // 2 <= base && base <= len(digits)
-
- var a [64 + 1]byte // +1 for sign of 64bit value in base 2
- i := len(a)
-
- if neg {
- u = -u
- }
-
- // convert bits
- if base == 10 {
- // common case: use constants for / because
- // the compiler can optimize it into a multiply+shift
-
- if ^uintptr(0)>>32 == 0 {
- for u > uint64(^uintptr(0)) {
- q := u / 1e9
- us := uintptr(u - q*1e9) // us % 1e9 fits into a uintptr
- for j := 9; j > 0; j-- {
- i--
- qs := us / 10
- a[i] = byte(us - qs*10 + '0')
- us = qs
- }
- u = q
- }
- }
-
- // u guaranteed to fit into a uintptr
- us := uintptr(u)
- for us >= 10 {
- i--
- q := us / 10
- a[i] = byte(us - q*10 + '0')
- us = q
- }
- // u < 10
- i--
- a[i] = byte(us + '0')
-
- } else if s := shifts[base]; s > 0 {
- // base is power of 2: use shifts and masks instead of / and %
- b := uint64(base)
- m := uintptr(b) - 1 // == 1<= b {
- i--
- a[i] = digits[uintptr(u)&m]
- u >>= s
- }
- // u < base
- i--
- a[i] = digits[uintptr(u)]
-
- } else {
- // general case
- b := uint64(base)
- for u >= b {
- i--
- q := u / b
- a[i] = digits[uintptr(u-q*b)]
- u = q
- }
- // u < base
- i--
- a[i] = digits[uintptr(u)]
- }
-
- // add sign, if any
- if neg {
- i--
- a[i] = '-'
- }
-
- dst.Write(a[i:])
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/internal/atof.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/internal/atof.go
deleted file mode 100644
index 46c1289e..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/internal/atof.go
+++ /dev/null
@@ -1,936 +0,0 @@
-/**
- * Copyright 2014 Paul Querna
- *
- * 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.
- *
- */
-
-/* Portions of this file are on Go stdlib's strconv/atof.go */
-
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package internal
-
-// decimal to binary floating point conversion.
-// Algorithm:
-// 1) Store input in multiprecision decimal.
-// 2) Multiply/divide decimal by powers of two until in range [0.5, 1)
-// 3) Multiply by 2^precision and round to get mantissa.
-
-import "math"
-
-var optimize = true // can change for testing
-
-func equalIgnoreCase(s1 []byte, s2 []byte) bool {
- if len(s1) != len(s2) {
- return false
- }
- for i := 0; i < len(s1); i++ {
- c1 := s1[i]
- if 'A' <= c1 && c1 <= 'Z' {
- c1 += 'a' - 'A'
- }
- c2 := s2[i]
- if 'A' <= c2 && c2 <= 'Z' {
- c2 += 'a' - 'A'
- }
- if c1 != c2 {
- return false
- }
- }
- return true
-}
-
-func special(s []byte) (f float64, ok bool) {
- if len(s) == 0 {
- return
- }
- switch s[0] {
- default:
- return
- case '+':
- if equalIgnoreCase(s, []byte("+inf")) || equalIgnoreCase(s, []byte("+infinity")) {
- return math.Inf(1), true
- }
- case '-':
- if equalIgnoreCase(s, []byte("-inf")) || equalIgnoreCase(s, []byte("-infinity")) {
- return math.Inf(-1), true
- }
- case 'n', 'N':
- if equalIgnoreCase(s, []byte("nan")) {
- return math.NaN(), true
- }
- case 'i', 'I':
- if equalIgnoreCase(s, []byte("inf")) || equalIgnoreCase(s, []byte("infinity")) {
- return math.Inf(1), true
- }
- }
- return
-}
-
-func (b *decimal) set(s []byte) (ok bool) {
- i := 0
- b.neg = false
- b.trunc = false
-
- // optional sign
- if i >= len(s) {
- return
- }
- switch {
- case s[i] == '+':
- i++
- case s[i] == '-':
- b.neg = true
- i++
- }
-
- // digits
- sawdot := false
- sawdigits := false
- for ; i < len(s); i++ {
- switch {
- case s[i] == '.':
- if sawdot {
- return
- }
- sawdot = true
- b.dp = b.nd
- continue
-
- case '0' <= s[i] && s[i] <= '9':
- sawdigits = true
- if s[i] == '0' && b.nd == 0 { // ignore leading zeros
- b.dp--
- continue
- }
- if b.nd < len(b.d) {
- b.d[b.nd] = s[i]
- b.nd++
- } else if s[i] != '0' {
- b.trunc = true
- }
- continue
- }
- break
- }
- if !sawdigits {
- return
- }
- if !sawdot {
- b.dp = b.nd
- }
-
- // optional exponent moves decimal point.
- // if we read a very large, very long number,
- // just be sure to move the decimal point by
- // a lot (say, 100000). it doesn't matter if it's
- // not the exact number.
- if i < len(s) && (s[i] == 'e' || s[i] == 'E') {
- i++
- if i >= len(s) {
- return
- }
- esign := 1
- if s[i] == '+' {
- i++
- } else if s[i] == '-' {
- i++
- esign = -1
- }
- if i >= len(s) || s[i] < '0' || s[i] > '9' {
- return
- }
- e := 0
- for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
- if e < 10000 {
- e = e*10 + int(s[i]) - '0'
- }
- }
- b.dp += e * esign
- }
-
- if i != len(s) {
- return
- }
-
- ok = true
- return
-}
-
-// readFloat reads a decimal mantissa and exponent from a float
-// string representation. It sets ok to false if the number could
-// not fit return types or is invalid.
-func readFloat(s []byte) (mantissa uint64, exp int, neg, trunc, ok bool) {
- const uint64digits = 19
- i := 0
-
- // optional sign
- if i >= len(s) {
- return
- }
- switch {
- case s[i] == '+':
- i++
- case s[i] == '-':
- neg = true
- i++
- }
-
- // digits
- sawdot := false
- sawdigits := false
- nd := 0
- ndMant := 0
- dp := 0
- for ; i < len(s); i++ {
- switch c := s[i]; true {
- case c == '.':
- if sawdot {
- return
- }
- sawdot = true
- dp = nd
- continue
-
- case '0' <= c && c <= '9':
- sawdigits = true
- if c == '0' && nd == 0 { // ignore leading zeros
- dp--
- continue
- }
- nd++
- if ndMant < uint64digits {
- mantissa *= 10
- mantissa += uint64(c - '0')
- ndMant++
- } else if s[i] != '0' {
- trunc = true
- }
- continue
- }
- break
- }
- if !sawdigits {
- return
- }
- if !sawdot {
- dp = nd
- }
-
- // optional exponent moves decimal point.
- // if we read a very large, very long number,
- // just be sure to move the decimal point by
- // a lot (say, 100000). it doesn't matter if it's
- // not the exact number.
- if i < len(s) && (s[i] == 'e' || s[i] == 'E') {
- i++
- if i >= len(s) {
- return
- }
- esign := 1
- if s[i] == '+' {
- i++
- } else if s[i] == '-' {
- i++
- esign = -1
- }
- if i >= len(s) || s[i] < '0' || s[i] > '9' {
- return
- }
- e := 0
- for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
- if e < 10000 {
- e = e*10 + int(s[i]) - '0'
- }
- }
- dp += e * esign
- }
-
- if i != len(s) {
- return
- }
-
- exp = dp - ndMant
- ok = true
- return
-
-}
-
-// decimal power of ten to binary power of two.
-var powtab = []int{1, 3, 6, 9, 13, 16, 19, 23, 26}
-
-func (d *decimal) floatBits(flt *floatInfo) (b uint64, overflow bool) {
- var exp int
- var mant uint64
-
- // Zero is always a special case.
- if d.nd == 0 {
- mant = 0
- exp = flt.bias
- goto out
- }
-
- // Obvious overflow/underflow.
- // These bounds are for 64-bit floats.
- // Will have to change if we want to support 80-bit floats in the future.
- if d.dp > 310 {
- goto overflow
- }
- if d.dp < -330 {
- // zero
- mant = 0
- exp = flt.bias
- goto out
- }
-
- // Scale by powers of two until in range [0.5, 1.0)
- exp = 0
- for d.dp > 0 {
- var n int
- if d.dp >= len(powtab) {
- n = 27
- } else {
- n = powtab[d.dp]
- }
- d.Shift(-n)
- exp += n
- }
- for d.dp < 0 || d.dp == 0 && d.d[0] < '5' {
- var n int
- if -d.dp >= len(powtab) {
- n = 27
- } else {
- n = powtab[-d.dp]
- }
- d.Shift(n)
- exp -= n
- }
-
- // Our range is [0.5,1) but floating point range is [1,2).
- exp--
-
- // Minimum representable exponent is flt.bias+1.
- // If the exponent is smaller, move it up and
- // adjust d accordingly.
- if exp < flt.bias+1 {
- n := flt.bias + 1 - exp
- d.Shift(-n)
- exp += n
- }
-
- if exp-flt.bias >= 1<>= 1
- exp++
- if exp-flt.bias >= 1<>float64info.mantbits != 0 {
- return
- }
- f = float64(mantissa)
- if neg {
- f = -f
- }
- switch {
- case exp == 0:
- // an integer.
- return f, true
- // Exact integers are <= 10^15.
- // Exact powers of ten are <= 10^22.
- case exp > 0 && exp <= 15+22: // int * 10^k
- // If exponent is big but number of digits is not,
- // can move a few zeros into the integer part.
- if exp > 22 {
- f *= float64pow10[exp-22]
- exp = 22
- }
- if f > 1e15 || f < -1e15 {
- // the exponent was really too large.
- return
- }
- return f * float64pow10[exp], true
- case exp < 0 && exp >= -22: // int / 10^k
- return f / float64pow10[-exp], true
- }
- return
-}
-
-// If possible to compute mantissa*10^exp to 32-bit float f exactly,
-// entirely in floating-point math, do so, avoiding the machinery above.
-func atof32exact(mantissa uint64, exp int, neg bool) (f float32, ok bool) {
- if mantissa>>float32info.mantbits != 0 {
- return
- }
- f = float32(mantissa)
- if neg {
- f = -f
- }
- switch {
- case exp == 0:
- return f, true
- // Exact integers are <= 10^7.
- // Exact powers of ten are <= 10^10.
- case exp > 0 && exp <= 7+10: // int * 10^k
- // If exponent is big but number of digits is not,
- // can move a few zeros into the integer part.
- if exp > 10 {
- f *= float32pow10[exp-10]
- exp = 10
- }
- if f > 1e7 || f < -1e7 {
- // the exponent was really too large.
- return
- }
- return f * float32pow10[exp], true
- case exp < 0 && exp >= -10: // int / 10^k
- return f / float32pow10[-exp], true
- }
- return
-}
-
-const fnParseFloat = "ParseFloat"
-
-func atof32(s []byte) (f float32, err error) {
- if val, ok := special(s); ok {
- return float32(val), nil
- }
-
- if optimize {
- // Parse mantissa and exponent.
- mantissa, exp, neg, trunc, ok := readFloat(s)
- if ok {
- // Try pure floating-point arithmetic conversion.
- if !trunc {
- if f, ok := atof32exact(mantissa, exp, neg); ok {
- return f, nil
- }
- }
- // Try another fast path.
- ext := new(extFloat)
- if ok := ext.AssignDecimal(mantissa, exp, neg, trunc, &float32info); ok {
- b, ovf := ext.floatBits(&float32info)
- f = math.Float32frombits(uint32(b))
- if ovf {
- err = rangeError(fnParseFloat, string(s))
- }
- return f, err
- }
- }
- }
- var d decimal
- if !d.set(s) {
- return 0, syntaxError(fnParseFloat, string(s))
- }
- b, ovf := d.floatBits(&float32info)
- f = math.Float32frombits(uint32(b))
- if ovf {
- err = rangeError(fnParseFloat, string(s))
- }
- return f, err
-}
-
-func atof64(s []byte) (f float64, err error) {
- if val, ok := special(s); ok {
- return val, nil
- }
-
- if optimize {
- // Parse mantissa and exponent.
- mantissa, exp, neg, trunc, ok := readFloat(s)
- if ok {
- // Try pure floating-point arithmetic conversion.
- if !trunc {
- if f, ok := atof64exact(mantissa, exp, neg); ok {
- return f, nil
- }
- }
- // Try another fast path.
- ext := new(extFloat)
- if ok := ext.AssignDecimal(mantissa, exp, neg, trunc, &float64info); ok {
- b, ovf := ext.floatBits(&float64info)
- f = math.Float64frombits(b)
- if ovf {
- err = rangeError(fnParseFloat, string(s))
- }
- return f, err
- }
- }
- }
- var d decimal
- if !d.set(s) {
- return 0, syntaxError(fnParseFloat, string(s))
- }
- b, ovf := d.floatBits(&float64info)
- f = math.Float64frombits(b)
- if ovf {
- err = rangeError(fnParseFloat, string(s))
- }
- return f, err
-}
-
-// ParseFloat converts the string s to a floating-point number
-// with the precision specified by bitSize: 32 for float32, or 64 for float64.
-// When bitSize=32, the result still has type float64, but it will be
-// convertible to float32 without changing its value.
-//
-// If s is well-formed and near a valid floating point number,
-// ParseFloat returns the nearest floating point number rounded
-// using IEEE754 unbiased rounding.
-//
-// The errors that ParseFloat returns have concrete type *NumError
-// and include err.Num = s.
-//
-// If s is not syntactically well-formed, ParseFloat returns err.Err = ErrSyntax.
-//
-// If s is syntactically well-formed but is more than 1/2 ULP
-// away from the largest floating point number of the given size,
-// ParseFloat returns f = ±Inf, err.Err = ErrRange.
-func ParseFloat(s []byte, bitSize int) (f float64, err error) {
- if bitSize == 32 {
- f1, err1 := atof32(s)
- return float64(f1), err1
- }
- f1, err1 := atof64(s)
- return f1, err1
-}
-
-// oroginal: strconv/decimal.go, but not exported, and needed for PareFloat.
-
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Multiprecision decimal numbers.
-// For floating-point formatting only; not general purpose.
-// Only operations are assign and (binary) left/right shift.
-// Can do binary floating point in multiprecision decimal precisely
-// because 2 divides 10; cannot do decimal floating point
-// in multiprecision binary precisely.
-
-type decimal struct {
- d [800]byte // digits
- nd int // number of digits used
- dp int // decimal point
- neg bool
- trunc bool // discarded nonzero digits beyond d[:nd]
-}
-
-func (a *decimal) String() string {
- n := 10 + a.nd
- if a.dp > 0 {
- n += a.dp
- }
- if a.dp < 0 {
- n += -a.dp
- }
-
- buf := make([]byte, n)
- w := 0
- switch {
- case a.nd == 0:
- return "0"
-
- case a.dp <= 0:
- // zeros fill space between decimal point and digits
- buf[w] = '0'
- w++
- buf[w] = '.'
- w++
- w += digitZero(buf[w : w+-a.dp])
- w += copy(buf[w:], a.d[0:a.nd])
-
- case a.dp < a.nd:
- // decimal point in middle of digits
- w += copy(buf[w:], a.d[0:a.dp])
- buf[w] = '.'
- w++
- w += copy(buf[w:], a.d[a.dp:a.nd])
-
- default:
- // zeros fill space between digits and decimal point
- w += copy(buf[w:], a.d[0:a.nd])
- w += digitZero(buf[w : w+a.dp-a.nd])
- }
- return string(buf[0:w])
-}
-
-func digitZero(dst []byte) int {
- for i := range dst {
- dst[i] = '0'
- }
- return len(dst)
-}
-
-// trim trailing zeros from number.
-// (They are meaningless; the decimal point is tracked
-// independent of the number of digits.)
-func trim(a *decimal) {
- for a.nd > 0 && a.d[a.nd-1] == '0' {
- a.nd--
- }
- if a.nd == 0 {
- a.dp = 0
- }
-}
-
-// Assign v to a.
-func (a *decimal) Assign(v uint64) {
- var buf [24]byte
-
- // Write reversed decimal in buf.
- n := 0
- for v > 0 {
- v1 := v / 10
- v -= 10 * v1
- buf[n] = byte(v + '0')
- n++
- v = v1
- }
-
- // Reverse again to produce forward decimal in a.d.
- a.nd = 0
- for n--; n >= 0; n-- {
- a.d[a.nd] = buf[n]
- a.nd++
- }
- a.dp = a.nd
- trim(a)
-}
-
-// Maximum shift that we can do in one pass without overflow.
-// Signed int has 31 bits, and we have to be able to accommodate 9<>k == 0; r++ {
- if r >= a.nd {
- if n == 0 {
- // a == 0; shouldn't get here, but handle anyway.
- a.nd = 0
- return
- }
- for n>>k == 0 {
- n = n * 10
- r++
- }
- break
- }
- c := int(a.d[r])
- n = n*10 + c - '0'
- }
- a.dp -= r - 1
-
- // Pick up a digit, put down a digit.
- for ; r < a.nd; r++ {
- c := int(a.d[r])
- dig := n >> k
- n -= dig << k
- a.d[w] = byte(dig + '0')
- w++
- n = n*10 + c - '0'
- }
-
- // Put down extra digits.
- for n > 0 {
- dig := n >> k
- n -= dig << k
- if w < len(a.d) {
- a.d[w] = byte(dig + '0')
- w++
- } else if dig > 0 {
- a.trunc = true
- }
- n = n * 10
- }
-
- a.nd = w
- trim(a)
-}
-
-// Cheat sheet for left shift: table indexed by shift count giving
-// number of new digits that will be introduced by that shift.
-//
-// For example, leftcheats[4] = {2, "625"}. That means that
-// if we are shifting by 4 (multiplying by 16), it will add 2 digits
-// when the string prefix is "625" through "999", and one fewer digit
-// if the string prefix is "000" through "624".
-//
-// Credit for this trick goes to Ken.
-
-type leftCheat struct {
- delta int // number of new digits
- cutoff string // minus one digit if original < a.
-}
-
-var leftcheats = []leftCheat{
- // Leading digits of 1/2^i = 5^i.
- // 5^23 is not an exact 64-bit floating point number,
- // so have to use bc for the math.
- /*
- seq 27 | sed 's/^/5^/' | bc |
- awk 'BEGIN{ print "\tleftCheat{ 0, \"\" }," }
- {
- log2 = log(2)/log(10)
- printf("\tleftCheat{ %d, \"%s\" },\t// * %d\n",
- int(log2*NR+1), $0, 2**NR)
- }'
- */
- {0, ""},
- {1, "5"}, // * 2
- {1, "25"}, // * 4
- {1, "125"}, // * 8
- {2, "625"}, // * 16
- {2, "3125"}, // * 32
- {2, "15625"}, // * 64
- {3, "78125"}, // * 128
- {3, "390625"}, // * 256
- {3, "1953125"}, // * 512
- {4, "9765625"}, // * 1024
- {4, "48828125"}, // * 2048
- {4, "244140625"}, // * 4096
- {4, "1220703125"}, // * 8192
- {5, "6103515625"}, // * 16384
- {5, "30517578125"}, // * 32768
- {5, "152587890625"}, // * 65536
- {6, "762939453125"}, // * 131072
- {6, "3814697265625"}, // * 262144
- {6, "19073486328125"}, // * 524288
- {7, "95367431640625"}, // * 1048576
- {7, "476837158203125"}, // * 2097152
- {7, "2384185791015625"}, // * 4194304
- {7, "11920928955078125"}, // * 8388608
- {8, "59604644775390625"}, // * 16777216
- {8, "298023223876953125"}, // * 33554432
- {8, "1490116119384765625"}, // * 67108864
- {9, "7450580596923828125"}, // * 134217728
-}
-
-// Is the leading prefix of b lexicographically less than s?
-func prefixIsLessThan(b []byte, s string) bool {
- for i := 0; i < len(s); i++ {
- if i >= len(b) {
- return true
- }
- if b[i] != s[i] {
- return b[i] < s[i]
- }
- }
- return false
-}
-
-// Binary shift left (/ 2) by k bits. k <= maxShift to avoid overflow.
-func leftShift(a *decimal, k uint) {
- delta := leftcheats[k].delta
- if prefixIsLessThan(a.d[0:a.nd], leftcheats[k].cutoff) {
- delta--
- }
-
- r := a.nd // read index
- w := a.nd + delta // write index
- n := 0
-
- // Pick up a digit, put down a digit.
- for r--; r >= 0; r-- {
- n += (int(a.d[r]) - '0') << k
- quo := n / 10
- rem := n - 10*quo
- w--
- if w < len(a.d) {
- a.d[w] = byte(rem + '0')
- } else if rem != 0 {
- a.trunc = true
- }
- n = quo
- }
-
- // Put down extra digits.
- for n > 0 {
- quo := n / 10
- rem := n - 10*quo
- w--
- if w < len(a.d) {
- a.d[w] = byte(rem + '0')
- } else if rem != 0 {
- a.trunc = true
- }
- n = quo
- }
-
- a.nd += delta
- if a.nd >= len(a.d) {
- a.nd = len(a.d)
- }
- a.dp += delta
- trim(a)
-}
-
-// Binary shift left (k > 0) or right (k < 0).
-func (a *decimal) Shift(k int) {
- switch {
- case a.nd == 0:
- // nothing to do: a == 0
- case k > 0:
- for k > maxShift {
- leftShift(a, maxShift)
- k -= maxShift
- }
- leftShift(a, uint(k))
- case k < 0:
- for k < -maxShift {
- rightShift(a, maxShift)
- k += maxShift
- }
- rightShift(a, uint(-k))
- }
-}
-
-// If we chop a at nd digits, should we round up?
-func shouldRoundUp(a *decimal, nd int) bool {
- if nd < 0 || nd >= a.nd {
- return false
- }
- if a.d[nd] == '5' && nd+1 == a.nd { // exactly halfway - round to even
- // if we truncated, a little higher than what's recorded - always round up
- if a.trunc {
- return true
- }
- return nd > 0 && (a.d[nd-1]-'0')%2 != 0
- }
- // not halfway - digit tells all
- return a.d[nd] >= '5'
-}
-
-// Round a to nd digits (or fewer).
-// If nd is zero, it means we're rounding
-// just to the left of the digits, as in
-// 0.09 -> 0.1.
-func (a *decimal) Round(nd int) {
- if nd < 0 || nd >= a.nd {
- return
- }
- if shouldRoundUp(a, nd) {
- a.RoundUp(nd)
- } else {
- a.RoundDown(nd)
- }
-}
-
-// Round a down to nd digits (or fewer).
-func (a *decimal) RoundDown(nd int) {
- if nd < 0 || nd >= a.nd {
- return
- }
- a.nd = nd
- trim(a)
-}
-
-// Round a up to nd digits (or fewer).
-func (a *decimal) RoundUp(nd int) {
- if nd < 0 || nd >= a.nd {
- return
- }
-
- // round up
- for i := nd - 1; i >= 0; i-- {
- c := a.d[i]
- if c < '9' { // can stop after this digit
- a.d[i]++
- a.nd = i + 1
- return
- }
- }
-
- // Number is all 9s.
- // Change to single 1 with adjusted decimal point.
- a.d[0] = '1'
- a.nd = 1
- a.dp++
-}
-
-// Extract integer part, rounded appropriately.
-// No guarantees about overflow.
-func (a *decimal) RoundedInteger() uint64 {
- if a.dp > 20 {
- return 0xFFFFFFFFFFFFFFFF
- }
- var i int
- n := uint64(0)
- for i = 0; i < a.dp && i < a.nd; i++ {
- n = n*10 + uint64(a.d[i]-'0')
- }
- for ; i < a.dp; i++ {
- n *= 10
- }
- if shouldRoundUp(a, a.dp) {
- n++
- }
- return n
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/internal/atoi.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/internal/atoi.go
deleted file mode 100644
index 06eb2ec2..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/internal/atoi.go
+++ /dev/null
@@ -1,213 +0,0 @@
-/**
- * Copyright 2014 Paul Querna
- *
- * 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.
- *
- */
-
-/* Portions of this file are on Go stdlib's strconv/atoi.go */
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package internal
-
-import (
- "errors"
- "strconv"
-)
-
-// ErrRange indicates that a value is out of range for the target type.
-var ErrRange = errors.New("value out of range")
-
-// ErrSyntax indicates that a value does not have the right syntax for the target type.
-var ErrSyntax = errors.New("invalid syntax")
-
-// A NumError records a failed conversion.
-type NumError struct {
- Func string // the failing function (ParseBool, ParseInt, ParseUint, ParseFloat)
- Num string // the input
- Err error // the reason the conversion failed (ErrRange, ErrSyntax)
-}
-
-func (e *NumError) Error() string {
- return "strconv." + e.Func + ": " + "parsing " + strconv.Quote(e.Num) + ": " + e.Err.Error()
-}
-
-func syntaxError(fn, str string) *NumError {
- return &NumError{fn, str, ErrSyntax}
-}
-
-func rangeError(fn, str string) *NumError {
- return &NumError{fn, str, ErrRange}
-}
-
-const intSize = 32 << uint(^uint(0)>>63)
-
-// IntSize is the size in bits of an int or uint value.
-const IntSize = intSize
-
-// Return the first number n such that n*base >= 1<<64.
-func cutoff64(base int) uint64 {
- if base < 2 {
- return 0
- }
- return (1<<64-1)/uint64(base) + 1
-}
-
-// ParseUint is like ParseInt but for unsigned numbers, and oeprating on []byte
-func ParseUint(s []byte, base int, bitSize int) (n uint64, err error) {
- var cutoff, maxVal uint64
-
- if bitSize == 0 {
- bitSize = int(IntSize)
- }
-
- s0 := s
- switch {
- case len(s) < 1:
- err = ErrSyntax
- goto Error
-
- case 2 <= base && base <= 36:
- // valid base; nothing to do
-
- case base == 0:
- // Look for octal, hex prefix.
- switch {
- case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
- base = 16
- s = s[2:]
- if len(s) < 1 {
- err = ErrSyntax
- goto Error
- }
- case s[0] == '0':
- base = 8
- default:
- base = 10
- }
-
- default:
- err = errors.New("invalid base " + strconv.Itoa(base))
- goto Error
- }
-
- n = 0
- cutoff = cutoff64(base)
- maxVal = 1<= base {
- n = 0
- err = ErrSyntax
- goto Error
- }
-
- if n >= cutoff {
- // n*base overflows
- n = 1<<64 - 1
- err = ErrRange
- goto Error
- }
- n *= uint64(base)
-
- n1 := n + uint64(v)
- if n1 < n || n1 > maxVal {
- // n+v overflows
- n = 1<<64 - 1
- err = ErrRange
- goto Error
- }
- n = n1
- }
-
- return n, nil
-
-Error:
- return n, &NumError{"ParseUint", string(s0), err}
-}
-
-// ParseInt interprets a string s in the given base (2 to 36) and
-// returns the corresponding value i. If base == 0, the base is
-// implied by the string's prefix: base 16 for "0x", base 8 for
-// "0", and base 10 otherwise.
-//
-// The bitSize argument specifies the integer type
-// that the result must fit into. Bit sizes 0, 8, 16, 32, and 64
-// correspond to int, int8, int16, int32, and int64.
-//
-// The errors that ParseInt returns have concrete type *NumError
-// and include err.Num = s. If s is empty or contains invalid
-// digits, err.Err = ErrSyntax and the returned value is 0;
-// if the value corresponding to s cannot be represented by a
-// signed integer of the given size, err.Err = ErrRange and the
-// returned value is the maximum magnitude integer of the
-// appropriate bitSize and sign.
-func ParseInt(s []byte, base int, bitSize int) (i int64, err error) {
- const fnParseInt = "ParseInt"
-
- if bitSize == 0 {
- bitSize = int(IntSize)
- }
-
- // Empty string bad.
- if len(s) == 0 {
- return 0, syntaxError(fnParseInt, string(s))
- }
-
- // Pick off leading sign.
- s0 := s
- neg := false
- if s[0] == '+' {
- s = s[1:]
- } else if s[0] == '-' {
- neg = true
- s = s[1:]
- }
-
- // Convert unsigned and check range.
- var un uint64
- un, err = ParseUint(s, base, bitSize)
- if err != nil && err.(*NumError).Err != ErrRange {
- err.(*NumError).Func = fnParseInt
- err.(*NumError).Num = string(s0)
- return 0, err
- }
- cutoff := uint64(1 << uint(bitSize-1))
- if !neg && un >= cutoff {
- return int64(cutoff - 1), rangeError(fnParseInt, string(s0))
- }
- if neg && un > cutoff {
- return -int64(cutoff), rangeError(fnParseInt, string(s0))
- }
- n := int64(un)
- if neg {
- n = -n
- }
- return n, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/internal/extfloat.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/internal/extfloat.go
deleted file mode 100644
index ab791085..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/internal/extfloat.go
+++ /dev/null
@@ -1,668 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package internal
-
-// An extFloat represents an extended floating-point number, with more
-// precision than a float64. It does not try to save bits: the
-// number represented by the structure is mant*(2^exp), with a negative
-// sign if neg is true.
-type extFloat struct {
- mant uint64
- exp int
- neg bool
-}
-
-// Powers of ten taken from double-conversion library.
-// http://code.google.com/p/double-conversion/
-const (
- firstPowerOfTen = -348
- stepPowerOfTen = 8
-)
-
-var smallPowersOfTen = [...]extFloat{
- {1 << 63, -63, false}, // 1
- {0xa << 60, -60, false}, // 1e1
- {0x64 << 57, -57, false}, // 1e2
- {0x3e8 << 54, -54, false}, // 1e3
- {0x2710 << 50, -50, false}, // 1e4
- {0x186a0 << 47, -47, false}, // 1e5
- {0xf4240 << 44, -44, false}, // 1e6
- {0x989680 << 40, -40, false}, // 1e7
-}
-
-var powersOfTen = [...]extFloat{
- {0xfa8fd5a0081c0288, -1220, false}, // 10^-348
- {0xbaaee17fa23ebf76, -1193, false}, // 10^-340
- {0x8b16fb203055ac76, -1166, false}, // 10^-332
- {0xcf42894a5dce35ea, -1140, false}, // 10^-324
- {0x9a6bb0aa55653b2d, -1113, false}, // 10^-316
- {0xe61acf033d1a45df, -1087, false}, // 10^-308
- {0xab70fe17c79ac6ca, -1060, false}, // 10^-300
- {0xff77b1fcbebcdc4f, -1034, false}, // 10^-292
- {0xbe5691ef416bd60c, -1007, false}, // 10^-284
- {0x8dd01fad907ffc3c, -980, false}, // 10^-276
- {0xd3515c2831559a83, -954, false}, // 10^-268
- {0x9d71ac8fada6c9b5, -927, false}, // 10^-260
- {0xea9c227723ee8bcb, -901, false}, // 10^-252
- {0xaecc49914078536d, -874, false}, // 10^-244
- {0x823c12795db6ce57, -847, false}, // 10^-236
- {0xc21094364dfb5637, -821, false}, // 10^-228
- {0x9096ea6f3848984f, -794, false}, // 10^-220
- {0xd77485cb25823ac7, -768, false}, // 10^-212
- {0xa086cfcd97bf97f4, -741, false}, // 10^-204
- {0xef340a98172aace5, -715, false}, // 10^-196
- {0xb23867fb2a35b28e, -688, false}, // 10^-188
- {0x84c8d4dfd2c63f3b, -661, false}, // 10^-180
- {0xc5dd44271ad3cdba, -635, false}, // 10^-172
- {0x936b9fcebb25c996, -608, false}, // 10^-164
- {0xdbac6c247d62a584, -582, false}, // 10^-156
- {0xa3ab66580d5fdaf6, -555, false}, // 10^-148
- {0xf3e2f893dec3f126, -529, false}, // 10^-140
- {0xb5b5ada8aaff80b8, -502, false}, // 10^-132
- {0x87625f056c7c4a8b, -475, false}, // 10^-124
- {0xc9bcff6034c13053, -449, false}, // 10^-116
- {0x964e858c91ba2655, -422, false}, // 10^-108
- {0xdff9772470297ebd, -396, false}, // 10^-100
- {0xa6dfbd9fb8e5b88f, -369, false}, // 10^-92
- {0xf8a95fcf88747d94, -343, false}, // 10^-84
- {0xb94470938fa89bcf, -316, false}, // 10^-76
- {0x8a08f0f8bf0f156b, -289, false}, // 10^-68
- {0xcdb02555653131b6, -263, false}, // 10^-60
- {0x993fe2c6d07b7fac, -236, false}, // 10^-52
- {0xe45c10c42a2b3b06, -210, false}, // 10^-44
- {0xaa242499697392d3, -183, false}, // 10^-36
- {0xfd87b5f28300ca0e, -157, false}, // 10^-28
- {0xbce5086492111aeb, -130, false}, // 10^-20
- {0x8cbccc096f5088cc, -103, false}, // 10^-12
- {0xd1b71758e219652c, -77, false}, // 10^-4
- {0x9c40000000000000, -50, false}, // 10^4
- {0xe8d4a51000000000, -24, false}, // 10^12
- {0xad78ebc5ac620000, 3, false}, // 10^20
- {0x813f3978f8940984, 30, false}, // 10^28
- {0xc097ce7bc90715b3, 56, false}, // 10^36
- {0x8f7e32ce7bea5c70, 83, false}, // 10^44
- {0xd5d238a4abe98068, 109, false}, // 10^52
- {0x9f4f2726179a2245, 136, false}, // 10^60
- {0xed63a231d4c4fb27, 162, false}, // 10^68
- {0xb0de65388cc8ada8, 189, false}, // 10^76
- {0x83c7088e1aab65db, 216, false}, // 10^84
- {0xc45d1df942711d9a, 242, false}, // 10^92
- {0x924d692ca61be758, 269, false}, // 10^100
- {0xda01ee641a708dea, 295, false}, // 10^108
- {0xa26da3999aef774a, 322, false}, // 10^116
- {0xf209787bb47d6b85, 348, false}, // 10^124
- {0xb454e4a179dd1877, 375, false}, // 10^132
- {0x865b86925b9bc5c2, 402, false}, // 10^140
- {0xc83553c5c8965d3d, 428, false}, // 10^148
- {0x952ab45cfa97a0b3, 455, false}, // 10^156
- {0xde469fbd99a05fe3, 481, false}, // 10^164
- {0xa59bc234db398c25, 508, false}, // 10^172
- {0xf6c69a72a3989f5c, 534, false}, // 10^180
- {0xb7dcbf5354e9bece, 561, false}, // 10^188
- {0x88fcf317f22241e2, 588, false}, // 10^196
- {0xcc20ce9bd35c78a5, 614, false}, // 10^204
- {0x98165af37b2153df, 641, false}, // 10^212
- {0xe2a0b5dc971f303a, 667, false}, // 10^220
- {0xa8d9d1535ce3b396, 694, false}, // 10^228
- {0xfb9b7cd9a4a7443c, 720, false}, // 10^236
- {0xbb764c4ca7a44410, 747, false}, // 10^244
- {0x8bab8eefb6409c1a, 774, false}, // 10^252
- {0xd01fef10a657842c, 800, false}, // 10^260
- {0x9b10a4e5e9913129, 827, false}, // 10^268
- {0xe7109bfba19c0c9d, 853, false}, // 10^276
- {0xac2820d9623bf429, 880, false}, // 10^284
- {0x80444b5e7aa7cf85, 907, false}, // 10^292
- {0xbf21e44003acdd2d, 933, false}, // 10^300
- {0x8e679c2f5e44ff8f, 960, false}, // 10^308
- {0xd433179d9c8cb841, 986, false}, // 10^316
- {0x9e19db92b4e31ba9, 1013, false}, // 10^324
- {0xeb96bf6ebadf77d9, 1039, false}, // 10^332
- {0xaf87023b9bf0ee6b, 1066, false}, // 10^340
-}
-
-// floatBits returns the bits of the float64 that best approximates
-// the extFloat passed as receiver. Overflow is set to true if
-// the resulting float64 is ±Inf.
-func (f *extFloat) floatBits(flt *floatInfo) (bits uint64, overflow bool) {
- f.Normalize()
-
- exp := f.exp + 63
-
- // Exponent too small.
- if exp < flt.bias+1 {
- n := flt.bias + 1 - exp
- f.mant >>= uint(n)
- exp += n
- }
-
- // Extract 1+flt.mantbits bits from the 64-bit mantissa.
- mant := f.mant >> (63 - flt.mantbits)
- if f.mant&(1<<(62-flt.mantbits)) != 0 {
- // Round up.
- mant += 1
- }
-
- // Rounding might have added a bit; shift down.
- if mant == 2<>= 1
- exp++
- }
-
- // Infinities.
- if exp-flt.bias >= 1<>uint(-f.exp))<>= uint(-f.exp)
- f.exp = 0
- return *f, *f
- }
- expBiased := exp - flt.bias
-
- upper = extFloat{mant: 2*f.mant + 1, exp: f.exp - 1, neg: f.neg}
- if mant != 1<>(64-32) == 0 {
- mant <<= 32
- exp -= 32
- }
- if mant>>(64-16) == 0 {
- mant <<= 16
- exp -= 16
- }
- if mant>>(64-8) == 0 {
- mant <<= 8
- exp -= 8
- }
- if mant>>(64-4) == 0 {
- mant <<= 4
- exp -= 4
- }
- if mant>>(64-2) == 0 {
- mant <<= 2
- exp -= 2
- }
- if mant>>(64-1) == 0 {
- mant <<= 1
- exp -= 1
- }
- shift = uint(f.exp - exp)
- f.mant, f.exp = mant, exp
- return
-}
-
-// Multiply sets f to the product f*g: the result is correctly rounded,
-// but not normalized.
-func (f *extFloat) Multiply(g extFloat) {
- fhi, flo := f.mant>>32, uint64(uint32(f.mant))
- ghi, glo := g.mant>>32, uint64(uint32(g.mant))
-
- // Cross products.
- cross1 := fhi * glo
- cross2 := flo * ghi
-
- // f.mant*g.mant is fhi*ghi << 64 + (cross1+cross2) << 32 + flo*glo
- f.mant = fhi*ghi + (cross1 >> 32) + (cross2 >> 32)
- rem := uint64(uint32(cross1)) + uint64(uint32(cross2)) + ((flo * glo) >> 32)
- // Round up.
- rem += (1 << 31)
-
- f.mant += (rem >> 32)
- f.exp = f.exp + g.exp + 64
-}
-
-var uint64pow10 = [...]uint64{
- 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
- 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
-}
-
-// AssignDecimal sets f to an approximate value mantissa*10^exp. It
-// returns true if the value represented by f is guaranteed to be the
-// best approximation of d after being rounded to a float64 or
-// float32 depending on flt.
-func (f *extFloat) AssignDecimal(mantissa uint64, exp10 int, neg bool, trunc bool, flt *floatInfo) (ok bool) {
- const uint64digits = 19
- const errorscale = 8
- errors := 0 // An upper bound for error, computed in errorscale*ulp.
- if trunc {
- // the decimal number was truncated.
- errors += errorscale / 2
- }
-
- f.mant = mantissa
- f.exp = 0
- f.neg = neg
-
- // Multiply by powers of ten.
- i := (exp10 - firstPowerOfTen) / stepPowerOfTen
- if exp10 < firstPowerOfTen || i >= len(powersOfTen) {
- return false
- }
- adjExp := (exp10 - firstPowerOfTen) % stepPowerOfTen
-
- // We multiply by exp%step
- if adjExp < uint64digits && mantissa < uint64pow10[uint64digits-adjExp] {
- // We can multiply the mantissa exactly.
- f.mant *= uint64pow10[adjExp]
- f.Normalize()
- } else {
- f.Normalize()
- f.Multiply(smallPowersOfTen[adjExp])
- errors += errorscale / 2
- }
-
- // We multiply by 10 to the exp - exp%step.
- f.Multiply(powersOfTen[i])
- if errors > 0 {
- errors += 1
- }
- errors += errorscale / 2
-
- // Normalize
- shift := f.Normalize()
- errors <<= shift
-
- // Now f is a good approximation of the decimal.
- // Check whether the error is too large: that is, if the mantissa
- // is perturbated by the error, the resulting float64 will change.
- // The 64 bits mantissa is 1 + 52 bits for float64 + 11 extra bits.
- //
- // In many cases the approximation will be good enough.
- denormalExp := flt.bias - 63
- var extrabits uint
- if f.exp <= denormalExp {
- // f.mant * 2^f.exp is smaller than 2^(flt.bias+1).
- extrabits = uint(63 - flt.mantbits + 1 + uint(denormalExp-f.exp))
- } else {
- extrabits = uint(63 - flt.mantbits)
- }
-
- halfway := uint64(1) << (extrabits - 1)
- mant_extra := f.mant & (1< expMax:
- i--
- default:
- break Loop
- }
- }
- // Apply the desired decimal shift on f. It will have exponent
- // in the desired range. This is multiplication by 10^-exp10.
- f.Multiply(powersOfTen[i])
-
- return -(firstPowerOfTen + i*stepPowerOfTen), i
-}
-
-// frexp10Many applies a common shift by a power of ten to a, b, c.
-func frexp10Many(a, b, c *extFloat) (exp10 int) {
- exp10, i := c.frexp10()
- a.Multiply(powersOfTen[i])
- b.Multiply(powersOfTen[i])
- return
-}
-
-// FixedDecimal stores in d the first n significant digits
-// of the decimal representation of f. It returns false
-// if it cannot be sure of the answer.
-func (f *extFloat) FixedDecimal(d *decimalSlice, n int) bool {
- if f.mant == 0 {
- d.nd = 0
- d.dp = 0
- d.neg = f.neg
- return true
- }
- if n == 0 {
- panic("strconv: internal error: extFloat.FixedDecimal called with n == 0")
- }
- // Multiply by an appropriate power of ten to have a reasonable
- // number to process.
- f.Normalize()
- exp10, _ := f.frexp10()
-
- shift := uint(-f.exp)
- integer := uint32(f.mant >> shift)
- fraction := f.mant - (uint64(integer) << shift)
- ε := uint64(1) // ε is the uncertainty we have on the mantissa of f.
-
- // Write exactly n digits to d.
- needed := n // how many digits are left to write.
- integerDigits := 0 // the number of decimal digits of integer.
- pow10 := uint64(1) // the power of ten by which f was scaled.
- for i, pow := 0, uint64(1); i < 20; i++ {
- if pow > uint64(integer) {
- integerDigits = i
- break
- }
- pow *= 10
- }
- rest := integer
- if integerDigits > needed {
- // the integral part is already large, trim the last digits.
- pow10 = uint64pow10[integerDigits-needed]
- integer /= uint32(pow10)
- rest -= integer * uint32(pow10)
- } else {
- rest = 0
- }
-
- // Write the digits of integer: the digits of rest are omitted.
- var buf [32]byte
- pos := len(buf)
- for v := integer; v > 0; {
- v1 := v / 10
- v -= 10 * v1
- pos--
- buf[pos] = byte(v + '0')
- v = v1
- }
- for i := pos; i < len(buf); i++ {
- d.d[i-pos] = buf[i]
- }
- nd := len(buf) - pos
- d.nd = nd
- d.dp = integerDigits + exp10
- needed -= nd
-
- if needed > 0 {
- if rest != 0 || pow10 != 1 {
- panic("strconv: internal error, rest != 0 but needed > 0")
- }
- // Emit digits for the fractional part. Each time, 10*fraction
- // fits in a uint64 without overflow.
- for needed > 0 {
- fraction *= 10
- ε *= 10 // the uncertainty scales as we multiply by ten.
- if 2*ε > 1<> shift
- d.d[nd] = byte(digit + '0')
- fraction -= digit << shift
- nd++
- needed--
- }
- d.nd = nd
- }
-
- // We have written a truncation of f (a numerator / 10^d.dp). The remaining part
- // can be interpreted as a small number (< 1) to be added to the last digit of the
- // numerator.
- //
- // If rest > 0, the amount is:
- // (rest< 0 guarantees that pow10 << shift does not overflow a uint64.
- //
- // If rest = 0, pow10 == 1 and the amount is
- // fraction / (1 << shift)
- // fraction being known with a ±ε uncertainty.
- //
- // We pass this information to the rounding routine for adjustment.
-
- ok := adjustLastDigitFixed(d, uint64(rest)<= 0; i-- {
- if d.d[i] != '0' {
- d.nd = i + 1
- break
- }
- }
- return true
-}
-
-// adjustLastDigitFixed assumes d contains the representation of the integral part
-// of some number, whose fractional part is num / (den << shift). The numerator
-// num is only known up to an uncertainty of size ε, assumed to be less than
-// (den << shift)/2.
-//
-// It will increase the last digit by one to account for correct rounding, typically
-// when the fractional part is greater than 1/2, and will return false if ε is such
-// that no correct answer can be given.
-func adjustLastDigitFixed(d *decimalSlice, num, den uint64, shift uint, ε uint64) bool {
- if num > den< den< den< (den< den<= 0; i-- {
- if d.d[i] == '9' {
- d.nd--
- } else {
- break
- }
- }
- if i < 0 {
- d.d[0] = '1'
- d.nd = 1
- d.dp++
- } else {
- d.d[i]++
- }
- return true
- }
- return false
-}
-
-// ShortestDecimal stores in d the shortest decimal representation of f
-// which belongs to the open interval (lower, upper), where f is supposed
-// to lie. It returns false whenever the result is unsure. The implementation
-// uses the Grisu3 algorithm.
-func (f *extFloat) ShortestDecimal(d *decimalSlice, lower, upper *extFloat) bool {
- if f.mant == 0 {
- d.nd = 0
- d.dp = 0
- d.neg = f.neg
- return true
- }
- if f.exp == 0 && *lower == *f && *lower == *upper {
- // an exact integer.
- var buf [24]byte
- n := len(buf) - 1
- for v := f.mant; v > 0; {
- v1 := v / 10
- v -= 10 * v1
- buf[n] = byte(v + '0')
- n--
- v = v1
- }
- nd := len(buf) - n - 1
- for i := 0; i < nd; i++ {
- d.d[i] = buf[n+1+i]
- }
- d.nd, d.dp = nd, nd
- for d.nd > 0 && d.d[d.nd-1] == '0' {
- d.nd--
- }
- if d.nd == 0 {
- d.dp = 0
- }
- d.neg = f.neg
- return true
- }
- upper.Normalize()
- // Uniformize exponents.
- if f.exp > upper.exp {
- f.mant <<= uint(f.exp - upper.exp)
- f.exp = upper.exp
- }
- if lower.exp > upper.exp {
- lower.mant <<= uint(lower.exp - upper.exp)
- lower.exp = upper.exp
- }
-
- exp10 := frexp10Many(lower, f, upper)
- // Take a safety margin due to rounding in frexp10Many, but we lose precision.
- upper.mant++
- lower.mant--
-
- // The shortest representation of f is either rounded up or down, but
- // in any case, it is a truncation of upper.
- shift := uint(-upper.exp)
- integer := uint32(upper.mant >> shift)
- fraction := upper.mant - (uint64(integer) << shift)
-
- // How far we can go down from upper until the result is wrong.
- allowance := upper.mant - lower.mant
- // How far we should go to get a very precise result.
- targetDiff := upper.mant - f.mant
-
- // Count integral digits: there are at most 10.
- var integerDigits int
- for i, pow := 0, uint64(1); i < 20; i++ {
- if pow > uint64(integer) {
- integerDigits = i
- break
- }
- pow *= 10
- }
- for i := 0; i < integerDigits; i++ {
- pow := uint64pow10[integerDigits-i-1]
- digit := integer / uint32(pow)
- d.d[i] = byte(digit + '0')
- integer -= digit * uint32(pow)
- // evaluate whether we should stop.
- if currentDiff := uint64(integer)<> shift)
- d.d[d.nd] = byte(digit + '0')
- d.nd++
- fraction -= uint64(digit) << shift
- if fraction < allowance*multiplier {
- // We are in the admissible range. Note that if allowance is about to
- // overflow, that is, allowance > 2^64/10, the condition is automatically
- // true due to the limited range of fraction.
- return adjustLastDigit(d,
- fraction, targetDiff*multiplier, allowance*multiplier,
- 1< maxDiff-ulpBinary {
- // we went too far
- return false
- }
- if d.nd == 1 && d.d[0] == '0' {
- // the number has actually reached zero.
- d.nd = 0
- d.dp = 0
- }
- return true
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/internal/ftoa.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/internal/ftoa.go
deleted file mode 100644
index 253f83b4..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/internal/ftoa.go
+++ /dev/null
@@ -1,475 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Binary to decimal floating point conversion.
-// Algorithm:
-// 1) store mantissa in multiprecision decimal
-// 2) shift decimal by exponent
-// 3) read digits out & format
-
-package internal
-
-import "math"
-
-// TODO: move elsewhere?
-type floatInfo struct {
- mantbits uint
- expbits uint
- bias int
-}
-
-var float32info = floatInfo{23, 8, -127}
-var float64info = floatInfo{52, 11, -1023}
-
-// FormatFloat converts the floating-point number f to a string,
-// according to the format fmt and precision prec. It rounds the
-// result assuming that the original was obtained from a floating-point
-// value of bitSize bits (32 for float32, 64 for float64).
-//
-// The format fmt is one of
-// 'b' (-ddddp±ddd, a binary exponent),
-// 'e' (-d.dddde±dd, a decimal exponent),
-// 'E' (-d.ddddE±dd, a decimal exponent),
-// 'f' (-ddd.dddd, no exponent),
-// 'g' ('e' for large exponents, 'f' otherwise), or
-// 'G' ('E' for large exponents, 'f' otherwise).
-//
-// The precision prec controls the number of digits
-// (excluding the exponent) printed by the 'e', 'E', 'f', 'g', and 'G' formats.
-// For 'e', 'E', and 'f' it is the number of digits after the decimal point.
-// For 'g' and 'G' it is the total number of digits.
-// The special precision -1 uses the smallest number of digits
-// necessary such that ParseFloat will return f exactly.
-func formatFloat(f float64, fmt byte, prec, bitSize int) string {
- return string(genericFtoa(make([]byte, 0, max(prec+4, 24)), f, fmt, prec, bitSize))
-}
-
-// AppendFloat appends the string form of the floating-point number f,
-// as generated by FormatFloat, to dst and returns the extended buffer.
-func appendFloat(dst []byte, f float64, fmt byte, prec int, bitSize int) []byte {
- return genericFtoa(dst, f, fmt, prec, bitSize)
-}
-
-func genericFtoa(dst []byte, val float64, fmt byte, prec, bitSize int) []byte {
- var bits uint64
- var flt *floatInfo
- switch bitSize {
- case 32:
- bits = uint64(math.Float32bits(float32(val)))
- flt = &float32info
- case 64:
- bits = math.Float64bits(val)
- flt = &float64info
- default:
- panic("strconv: illegal AppendFloat/FormatFloat bitSize")
- }
-
- neg := bits>>(flt.expbits+flt.mantbits) != 0
- exp := int(bits>>flt.mantbits) & (1< digs.nd && digs.nd >= digs.dp {
- eprec = digs.nd
- }
- // %e is used if the exponent from the conversion
- // is less than -4 or greater than or equal to the precision.
- // if precision was the shortest possible, use precision 6 for this decision.
- if shortest {
- eprec = 6
- }
- exp := digs.dp - 1
- if exp < -4 || exp >= eprec {
- if prec > digs.nd {
- prec = digs.nd
- }
- return fmtE(dst, neg, digs, prec-1, fmt+'e'-'g')
- }
- if prec > digs.dp {
- prec = digs.nd
- }
- return fmtF(dst, neg, digs, max(prec-digs.dp, 0))
- }
-
- // unknown format
- return append(dst, '%', fmt)
-}
-
-// Round d (= mant * 2^exp) to the shortest number of digits
-// that will let the original floating point value be precisely
-// reconstructed. Size is original floating point size (64 or 32).
-func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) {
- // If mantissa is zero, the number is zero; stop now.
- if mant == 0 {
- d.nd = 0
- return
- }
-
- // Compute upper and lower such that any decimal number
- // between upper and lower (possibly inclusive)
- // will round to the original floating point number.
-
- // We may see at once that the number is already shortest.
- //
- // Suppose d is not denormal, so that 2^exp <= d < 10^dp.
- // The closest shorter number is at least 10^(dp-nd) away.
- // The lower/upper bounds computed below are at distance
- // at most 2^(exp-mantbits).
- //
- // So the number is already shortest if 10^(dp-nd) > 2^(exp-mantbits),
- // or equivalently log2(10)*(dp-nd) > exp-mantbits.
- // It is true if 332/100*(dp-nd) >= exp-mantbits (log2(10) > 3.32).
- minexp := flt.bias + 1 // minimum possible exponent
- if exp > minexp && 332*(d.dp-d.nd) >= 100*(exp-int(flt.mantbits)) {
- // The number is already shortest.
- return
- }
-
- // d = mant << (exp - mantbits)
- // Next highest floating point number is mant+1 << exp-mantbits.
- // Our upper bound is halfway between, mant*2+1 << exp-mantbits-1.
- upper := new(decimal)
- upper.Assign(mant*2 + 1)
- upper.Shift(exp - int(flt.mantbits) - 1)
-
- // d = mant << (exp - mantbits)
- // Next lowest floating point number is mant-1 << exp-mantbits,
- // unless mant-1 drops the significant bit and exp is not the minimum exp,
- // in which case the next lowest is mant*2-1 << exp-mantbits-1.
- // Either way, call it mantlo << explo-mantbits.
- // Our lower bound is halfway between, mantlo*2+1 << explo-mantbits-1.
- var mantlo uint64
- var explo int
- if mant > 1< 0 {
- dst = append(dst, '.')
- i := 1
- m := d.nd + prec + 1 - max(d.nd, prec+1)
- for i < m {
- dst = append(dst, d.d[i])
- i++
- }
- for i <= prec {
- dst = append(dst, '0')
- i++
- }
- }
-
- // e±
- dst = append(dst, fmt)
- exp := d.dp - 1
- if d.nd == 0 { // special case: 0 has exponent 0
- exp = 0
- }
- if exp < 0 {
- ch = '-'
- exp = -exp
- } else {
- ch = '+'
- }
- dst = append(dst, ch)
-
- // dddd
- var buf [3]byte
- i := len(buf)
- for exp >= 10 {
- i--
- buf[i] = byte(exp%10 + '0')
- exp /= 10
- }
- // exp < 10
- i--
- buf[i] = byte(exp + '0')
-
- switch i {
- case 0:
- dst = append(dst, buf[0], buf[1], buf[2])
- case 1:
- dst = append(dst, buf[1], buf[2])
- case 2:
- // leading zeroes
- dst = append(dst, '0', buf[2])
- }
- return dst
-}
-
-// %f: -ddddddd.ddddd
-func fmtF(dst []byte, neg bool, d decimalSlice, prec int) []byte {
- // sign
- if neg {
- dst = append(dst, '-')
- }
-
- // integer, padded with zeros as needed.
- if d.dp > 0 {
- var i int
- for i = 0; i < d.dp && i < d.nd; i++ {
- dst = append(dst, d.d[i])
- }
- for ; i < d.dp; i++ {
- dst = append(dst, '0')
- }
- } else {
- dst = append(dst, '0')
- }
-
- // fraction
- if prec > 0 {
- dst = append(dst, '.')
- for i := 0; i < prec; i++ {
- ch := byte('0')
- if j := d.dp + i; 0 <= j && j < d.nd {
- ch = d.d[j]
- }
- dst = append(dst, ch)
- }
- }
-
- return dst
-}
-
-// %b: -ddddddddp+ddd
-func fmtB(dst []byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte {
- var buf [50]byte
- w := len(buf)
- exp -= int(flt.mantbits)
- esign := byte('+')
- if exp < 0 {
- esign = '-'
- exp = -exp
- }
- n := 0
- for exp > 0 || n < 1 {
- n++
- w--
- buf[w] = byte(exp%10 + '0')
- exp /= 10
- }
- w--
- buf[w] = esign
- w--
- buf[w] = 'p'
- n = 0
- for mant > 0 || n < 1 {
- n++
- w--
- buf[w] = byte(mant%10 + '0')
- mant /= 10
- }
- if neg {
- w--
- buf[w] = '-'
- }
- return append(dst, buf[w:]...)
-}
-
-func max(a, b int) int {
- if a > b {
- return a
- }
- return b
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/iota.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/iota.go
deleted file mode 100644
index 3e50f0c4..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/iota.go
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
- * Copyright 2014 Paul Querna
- *
- * 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.
- *
- */
-
-/* Portions of this file are on Go stdlib's strconv/iota.go */
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package v1
-
-import (
- "io"
-)
-
-const (
- digits = "0123456789abcdefghijklmnopqrstuvwxyz"
- digits01 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
- digits10 = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999"
-)
-
-var shifts = [len(digits) + 1]uint{
- 1 << 1: 1,
- 1 << 2: 2,
- 1 << 3: 3,
- 1 << 4: 4,
- 1 << 5: 5,
-}
-
-var smallNumbers = [][]byte{
- []byte("0"),
- []byte("1"),
- []byte("2"),
- []byte("3"),
- []byte("4"),
- []byte("5"),
- []byte("6"),
- []byte("7"),
- []byte("8"),
- []byte("9"),
- []byte("10"),
-}
-
-type FormatBitsWriter interface {
- io.Writer
- io.ByteWriter
-}
-
-type FormatBitsScratch struct{}
-
-//
-// DEPRECIATED: `scratch` is no longer used, FormatBits2 is available.
-//
-// FormatBits computes the string representation of u in the given base.
-// If neg is set, u is treated as negative int64 value. If append_ is
-// set, the string is appended to dst and the resulting byte slice is
-// returned as the first result value; otherwise the string is returned
-// as the second result value.
-//
-func FormatBits(scratch *FormatBitsScratch, dst FormatBitsWriter, u uint64, base int, neg bool) {
- FormatBits2(dst, u, base, neg)
-}
-
-// FormatBits2 computes the string representation of u in the given base.
-// If neg is set, u is treated as negative int64 value. If append_ is
-// set, the string is appended to dst and the resulting byte slice is
-// returned as the first result value; otherwise the string is returned
-// as the second result value.
-//
-func FormatBits2(dst FormatBitsWriter, u uint64, base int, neg bool) {
- if base < 2 || base > len(digits) {
- panic("strconv: illegal AppendInt/FormatInt base")
- }
- // fast path for small common numbers
- if u <= 10 {
- if neg {
- dst.WriteByte('-')
- }
- dst.Write(smallNumbers[u])
- return
- }
-
- // 2 <= base && base <= len(digits)
-
- var a = makeSlice(65)
- // var a [64 + 1]byte // +1 for sign of 64bit value in base 2
- i := len(a)
-
- if neg {
- u = -u
- }
-
- // convert bits
- if base == 10 {
- // common case: use constants for / and % because
- // the compiler can optimize it into a multiply+shift,
- // and unroll loop
- for u >= 100 {
- i -= 2
- q := u / 100
- j := uintptr(u - q*100)
- a[i+1] = digits01[j]
- a[i+0] = digits10[j]
- u = q
- }
- if u >= 10 {
- i--
- q := u / 10
- a[i] = digits[uintptr(u-q*10)]
- u = q
- }
-
- } else if s := shifts[base]; s > 0 {
- // base is power of 2: use shifts and masks instead of / and %
- b := uint64(base)
- m := uintptr(b) - 1 // == 1<= b {
- i--
- a[i] = digits[uintptr(u)&m]
- u >>= s
- }
-
- } else {
- // general case
- b := uint64(base)
- for u >= b {
- i--
- a[i] = digits[uintptr(u%b)]
- u /= b
- }
- }
-
- // u < base
- i--
- a[i] = digits[uintptr(u)]
-
- // add sign, if any
- if neg {
- i--
- a[i] = '-'
- }
-
- dst.Write(a[i:])
-
- Pool(a)
-
- return
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/jsonstring.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/jsonstring.go
deleted file mode 100644
index 513b45d5..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/jsonstring.go
+++ /dev/null
@@ -1,512 +0,0 @@
-/**
- * Copyright 2014 Paul Querna
- *
- * 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.
- *
- */
-
-/* Portions of this file are on Go stdlib's encoding/json/encode.go */
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package v1
-
-import (
- "io"
- "unicode/utf8"
- "strconv"
- "unicode/utf16"
- "unicode"
-)
-
-const hex = "0123456789abcdef"
-
-type JsonStringWriter interface {
- io.Writer
- io.ByteWriter
- stringWriter
-}
-
-func WriteJsonString(buf JsonStringWriter, s string) {
- WriteJson(buf, []byte(s))
-}
-
-/**
- * Function ported from encoding/json: func (e *encodeState) string(s string) (int, error)
- */
-func WriteJson(buf JsonStringWriter, s []byte) {
- buf.WriteByte('"')
- start := 0
- for i := 0; i < len(s); {
- if b := s[i]; b < utf8.RuneSelf {
- /*
- if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
- i++
- continue
- }
- */
- if lt[b] == true {
- i++
- continue
- }
-
- if start < i {
- buf.Write(s[start:i])
- }
- switch b {
- case '\\', '"':
- buf.WriteByte('\\')
- buf.WriteByte(b)
- case '\n':
- buf.WriteByte('\\')
- buf.WriteByte('n')
- case '\r':
- buf.WriteByte('\\')
- buf.WriteByte('r')
- default:
- // This encodes bytes < 0x20 except for \n and \r,
- // as well as < and >. The latter are escaped because they
- // can lead to security holes when user-controlled strings
- // are rendered into JSON and served to some browsers.
- buf.WriteString(`\u00`)
- buf.WriteByte(hex[b>>4])
- buf.WriteByte(hex[b&0xF])
- }
- i++
- start = i
- continue
- }
- c, size := utf8.DecodeRune(s[i:])
- if c == utf8.RuneError && size == 1 {
- if start < i {
- buf.Write(s[start:i])
- }
- buf.WriteString(`\ufffd`)
- i += size
- start = i
- continue
- }
- // U+2028 is LINE SEPARATOR.
- // U+2029 is PARAGRAPH SEPARATOR.
- // They are both technically valid characters in JSON strings,
- // but don't work in JSONP, which has to be evaluated as JavaScript,
- // and can lead to security holes there. It is valid JSON to
- // escape them, so we do so unconditionally.
- // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
- if c == '\u2028' || c == '\u2029' {
- if start < i {
- buf.Write(s[start:i])
- }
- buf.WriteString(`\u202`)
- buf.WriteByte(hex[c&0xF])
- i += size
- start = i
- continue
- }
- i += size
- }
- if start < len(s) {
- buf.Write(s[start:])
- }
- buf.WriteByte('"')
-}
-
-// UnquoteBytes will decode []byte containing json string to go string
-// ported from encoding/json/decode.go
-func UnquoteBytes(s []byte) (t []byte, ok bool) {
- if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' {
- return
- }
- s = s[1 : len(s)-1]
-
- // Check for unusual characters. If there are none,
- // then no unquoting is needed, so return a slice of the
- // original bytes.
- r := 0
- for r < len(s) {
- c := s[r]
- if c == '\\' || c == '"' || c < ' ' {
- break
- }
- if c < utf8.RuneSelf {
- r++
- continue
- }
- rr, size := utf8.DecodeRune(s[r:])
- if rr == utf8.RuneError && size == 1 {
- break
- }
- r += size
- }
- if r == len(s) {
- return s, true
- }
-
- b := make([]byte, len(s)+2*utf8.UTFMax)
- w := copy(b, s[0:r])
- for r < len(s) {
- // Out of room? Can only happen if s is full of
- // malformed UTF-8 and we're replacing each
- // byte with RuneError.
- if w >= len(b)-2*utf8.UTFMax {
- nb := make([]byte, (len(b)+utf8.UTFMax)*2)
- copy(nb, b[0:w])
- b = nb
- }
- switch c := s[r]; {
- case c == '\\':
- r++
- if r >= len(s) {
- return
- }
- switch s[r] {
- default:
- return
- case '"', '\\', '/', '\'':
- b[w] = s[r]
- r++
- w++
- case 'b':
- b[w] = '\b'
- r++
- w++
- case 'f':
- b[w] = '\f'
- r++
- w++
- case 'n':
- b[w] = '\n'
- r++
- w++
- case 'r':
- b[w] = '\r'
- r++
- w++
- case 't':
- b[w] = '\t'
- r++
- w++
- case 'u':
- r--
- rr := getu4(s[r:])
- if rr < 0 {
- return
- }
- r += 6
- if utf16.IsSurrogate(rr) {
- rr1 := getu4(s[r:])
- if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar {
- // A valid pair; consume.
- r += 6
- w += utf8.EncodeRune(b[w:], dec)
- break
- }
- // Invalid surrogate; fall back to replacement rune.
- rr = unicode.ReplacementChar
- }
- w += utf8.EncodeRune(b[w:], rr)
- }
-
- // Quote, control characters are invalid.
- case c == '"', c < ' ':
- return
-
- // ASCII
- case c < utf8.RuneSelf:
- b[w] = c
- r++
- w++
-
- // Coerce to well-formed UTF-8.
- default:
- rr, size := utf8.DecodeRune(s[r:])
- r += size
- w += utf8.EncodeRune(b[w:], rr)
- }
- }
- return b[0:w], true
-}
-
-// getu4 decodes \uXXXX from the beginning of s, returning the hex value,
-// or it returns -1.
-func getu4(s []byte) rune {
- if len(s) < 6 || s[0] != '\\' || s[1] != 'u' {
- return -1
- }
- r, err := strconv.ParseUint(string(s[2:6]), 16, 64)
- if err != nil {
- return -1
- }
- return rune(r)
-}
-
-// TODO(pquerna): consider combining wibth the normal byte mask.
-var lt [256]bool = [256]bool{
- false, /* 0 */
- false, /* 1 */
- false, /* 2 */
- false, /* 3 */
- false, /* 4 */
- false, /* 5 */
- false, /* 6 */
- false, /* 7 */
- false, /* 8 */
- false, /* 9 */
- false, /* 10 */
- false, /* 11 */
- false, /* 12 */
- false, /* 13 */
- false, /* 14 */
- false, /* 15 */
- false, /* 16 */
- false, /* 17 */
- false, /* 18 */
- false, /* 19 */
- false, /* 20 */
- false, /* 21 */
- false, /* 22 */
- false, /* 23 */
- false, /* 24 */
- false, /* 25 */
- false, /* 26 */
- false, /* 27 */
- false, /* 28 */
- false, /* 29 */
- false, /* 30 */
- false, /* 31 */
- true, /* 32 */
- true, /* 33 */
- false, /* 34 */
- true, /* 35 */
- true, /* 36 */
- true, /* 37 */
- false, /* 38 */
- true, /* 39 */
- true, /* 40 */
- true, /* 41 */
- true, /* 42 */
- true, /* 43 */
- true, /* 44 */
- true, /* 45 */
- true, /* 46 */
- true, /* 47 */
- true, /* 48 */
- true, /* 49 */
- true, /* 50 */
- true, /* 51 */
- true, /* 52 */
- true, /* 53 */
- true, /* 54 */
- true, /* 55 */
- true, /* 56 */
- true, /* 57 */
- true, /* 58 */
- true, /* 59 */
- false, /* 60 */
- true, /* 61 */
- false, /* 62 */
- true, /* 63 */
- true, /* 64 */
- true, /* 65 */
- true, /* 66 */
- true, /* 67 */
- true, /* 68 */
- true, /* 69 */
- true, /* 70 */
- true, /* 71 */
- true, /* 72 */
- true, /* 73 */
- true, /* 74 */
- true, /* 75 */
- true, /* 76 */
- true, /* 77 */
- true, /* 78 */
- true, /* 79 */
- true, /* 80 */
- true, /* 81 */
- true, /* 82 */
- true, /* 83 */
- true, /* 84 */
- true, /* 85 */
- true, /* 86 */
- true, /* 87 */
- true, /* 88 */
- true, /* 89 */
- true, /* 90 */
- true, /* 91 */
- false, /* 92 */
- true, /* 93 */
- true, /* 94 */
- true, /* 95 */
- true, /* 96 */
- true, /* 97 */
- true, /* 98 */
- true, /* 99 */
- true, /* 100 */
- true, /* 101 */
- true, /* 102 */
- true, /* 103 */
- true, /* 104 */
- true, /* 105 */
- true, /* 106 */
- true, /* 107 */
- true, /* 108 */
- true, /* 109 */
- true, /* 110 */
- true, /* 111 */
- true, /* 112 */
- true, /* 113 */
- true, /* 114 */
- true, /* 115 */
- true, /* 116 */
- true, /* 117 */
- true, /* 118 */
- true, /* 119 */
- true, /* 120 */
- true, /* 121 */
- true, /* 122 */
- true, /* 123 */
- true, /* 124 */
- true, /* 125 */
- true, /* 126 */
- true, /* 127 */
- true, /* 128 */
- true, /* 129 */
- true, /* 130 */
- true, /* 131 */
- true, /* 132 */
- true, /* 133 */
- true, /* 134 */
- true, /* 135 */
- true, /* 136 */
- true, /* 137 */
- true, /* 138 */
- true, /* 139 */
- true, /* 140 */
- true, /* 141 */
- true, /* 142 */
- true, /* 143 */
- true, /* 144 */
- true, /* 145 */
- true, /* 146 */
- true, /* 147 */
- true, /* 148 */
- true, /* 149 */
- true, /* 150 */
- true, /* 151 */
- true, /* 152 */
- true, /* 153 */
- true, /* 154 */
- true, /* 155 */
- true, /* 156 */
- true, /* 157 */
- true, /* 158 */
- true, /* 159 */
- true, /* 160 */
- true, /* 161 */
- true, /* 162 */
- true, /* 163 */
- true, /* 164 */
- true, /* 165 */
- true, /* 166 */
- true, /* 167 */
- true, /* 168 */
- true, /* 169 */
- true, /* 170 */
- true, /* 171 */
- true, /* 172 */
- true, /* 173 */
- true, /* 174 */
- true, /* 175 */
- true, /* 176 */
- true, /* 177 */
- true, /* 178 */
- true, /* 179 */
- true, /* 180 */
- true, /* 181 */
- true, /* 182 */
- true, /* 183 */
- true, /* 184 */
- true, /* 185 */
- true, /* 186 */
- true, /* 187 */
- true, /* 188 */
- true, /* 189 */
- true, /* 190 */
- true, /* 191 */
- true, /* 192 */
- true, /* 193 */
- true, /* 194 */
- true, /* 195 */
- true, /* 196 */
- true, /* 197 */
- true, /* 198 */
- true, /* 199 */
- true, /* 200 */
- true, /* 201 */
- true, /* 202 */
- true, /* 203 */
- true, /* 204 */
- true, /* 205 */
- true, /* 206 */
- true, /* 207 */
- true, /* 208 */
- true, /* 209 */
- true, /* 210 */
- true, /* 211 */
- true, /* 212 */
- true, /* 213 */
- true, /* 214 */
- true, /* 215 */
- true, /* 216 */
- true, /* 217 */
- true, /* 218 */
- true, /* 219 */
- true, /* 220 */
- true, /* 221 */
- true, /* 222 */
- true, /* 223 */
- true, /* 224 */
- true, /* 225 */
- true, /* 226 */
- true, /* 227 */
- true, /* 228 */
- true, /* 229 */
- true, /* 230 */
- true, /* 231 */
- true, /* 232 */
- true, /* 233 */
- true, /* 234 */
- true, /* 235 */
- true, /* 236 */
- true, /* 237 */
- true, /* 238 */
- true, /* 239 */
- true, /* 240 */
- true, /* 241 */
- true, /* 242 */
- true, /* 243 */
- true, /* 244 */
- true, /* 245 */
- true, /* 246 */
- true, /* 247 */
- true, /* 248 */
- true, /* 249 */
- true, /* 250 */
- true, /* 251 */
- true, /* 252 */
- true, /* 253 */
- true, /* 254 */
- true, /* 255 */
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/lexer.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/lexer.go
deleted file mode 100644
index fbbb65d1..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/lexer.go
+++ /dev/null
@@ -1,944 +0,0 @@
-/**
- * Copyright 2014 Paul Querna
- *
- * 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.
- *
- */
-
-/* Portions of this file are on derived from yajl: */
-/*
- * Copyright (c) 2007-2014, Lloyd Hilaiel
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-package v1
-
-import (
- "errors"
- "fmt"
- "io"
-)
-
-type FFParseState int
-
-const (
- FFParse_map_start FFParseState = iota
- FFParse_want_key
- FFParse_want_colon
- FFParse_want_value
- FFParse_after_value
-)
-
-type FFTok int
-
-const (
- FFTok_init FFTok = iota
- FFTok_bool FFTok = iota
- FFTok_colon FFTok = iota
- FFTok_comma FFTok = iota
- FFTok_eof FFTok = iota
- FFTok_error FFTok = iota
- FFTok_left_brace FFTok = iota
- FFTok_left_bracket FFTok = iota
- FFTok_null FFTok = iota
- FFTok_right_brace FFTok = iota
- FFTok_right_bracket FFTok = iota
-
- /* we differentiate between integers and doubles to allow the
- * parser to interpret the number without re-scanning */
- FFTok_integer FFTok = iota
- FFTok_double FFTok = iota
-
- FFTok_string FFTok = iota
-
- /* comment tokens are not currently returned to the parser, ever */
- FFTok_comment FFTok = iota
-)
-
-type FFErr int
-
-const (
- FFErr_e_ok FFErr = iota
- FFErr_io FFErr = iota
- FFErr_string_invalid_utf8 FFErr = iota
- FFErr_string_invalid_escaped_char FFErr = iota
- FFErr_string_invalid_json_char FFErr = iota
- FFErr_string_invalid_hex_char FFErr = iota
- FFErr_invalid_char FFErr = iota
- FFErr_invalid_string FFErr = iota
- FFErr_missing_integer_after_decimal FFErr = iota
- FFErr_missing_integer_after_exponent FFErr = iota
- FFErr_missing_integer_after_minus FFErr = iota
- FFErr_unallowed_comment FFErr = iota
- FFErr_incomplete_comment FFErr = iota
- FFErr_unexpected_token_type FFErr = iota // TODO: improve this error
-)
-
-type FFLexer struct {
- reader *ffReader
- Output DecodingBuffer
- Token FFTok
- Error FFErr
- BigError error
- // TODO: convert all of this to an interface
- lastCurrentChar int
- captureAll bool
- buf Buffer
-}
-
-func NewFFLexer(input []byte) *FFLexer {
- fl := &FFLexer{
- Token: FFTok_init,
- Error: FFErr_e_ok,
- reader: newffReader(input),
- Output: &Buffer{},
- }
- // TODO: guess size?
- //fl.Output.Grow(64)
- return fl
-}
-
-type LexerError struct {
- offset int
- line int
- char int
- err error
-}
-
-// Reset the Lexer and add new input.
-func (ffl *FFLexer) Reset(input []byte) {
- ffl.Token = FFTok_init
- ffl.Error = FFErr_e_ok
- ffl.BigError = nil
- ffl.reader.Reset(input)
- ffl.lastCurrentChar = 0
- ffl.Output.Reset()
-}
-
-func (le *LexerError) Error() string {
- return fmt.Sprintf(`ffjson error: (%T)%s offset=%d line=%d char=%d`,
- le.err, le.err.Error(),
- le.offset, le.line, le.char)
-}
-
-func (ffl *FFLexer) WrapErr(err error) error {
- line, char := ffl.reader.PosWithLine()
- // TOOD: calcualte lines/characters based on offset
- return &LexerError{
- offset: ffl.reader.Pos(),
- line: line,
- char: char,
- err: err,
- }
-}
-
-func (ffl *FFLexer) scanReadByte() (byte, error) {
- var c byte
- var err error
- if ffl.captureAll {
- c, err = ffl.reader.ReadByte()
- } else {
- c, err = ffl.reader.ReadByteNoWS()
- }
-
- if err != nil {
- ffl.Error = FFErr_io
- ffl.BigError = err
- return 0, err
- }
-
- return c, nil
-}
-
-func (ffl *FFLexer) readByte() (byte, error) {
-
- c, err := ffl.reader.ReadByte()
- if err != nil {
- ffl.Error = FFErr_io
- ffl.BigError = err
- return 0, err
- }
-
- return c, nil
-}
-
-func (ffl *FFLexer) unreadByte() {
- ffl.reader.UnreadByte()
-}
-
-func (ffl *FFLexer) wantBytes(want []byte, iftrue FFTok) FFTok {
- for _, b := range want {
- c, err := ffl.readByte()
-
- if err != nil {
- return FFTok_error
- }
-
- if c != b {
- ffl.unreadByte()
- // fmt.Printf("wanted bytes: %s\n", string(want))
- // TODO(pquerna): thsi is a bad error message
- ffl.Error = FFErr_invalid_string
- return FFTok_error
- }
-
- ffl.Output.WriteByte(c)
- }
-
- return iftrue
-}
-
-func (ffl *FFLexer) lexComment() FFTok {
- c, err := ffl.readByte()
- if err != nil {
- return FFTok_error
- }
-
- if c == '/' {
- // a // comment, scan until line ends.
- for {
- c, err := ffl.readByte()
- if err != nil {
- return FFTok_error
- }
-
- if c == '\n' {
- return FFTok_comment
- }
- }
- } else if c == '*' {
- // a /* */ comment, scan */
- for {
- c, err := ffl.readByte()
- if err != nil {
- return FFTok_error
- }
-
- if c == '*' {
- c, err := ffl.readByte()
-
- if err != nil {
- return FFTok_error
- }
-
- if c == '/' {
- return FFTok_comment
- }
-
- ffl.Error = FFErr_incomplete_comment
- return FFTok_error
- }
- }
- } else {
- ffl.Error = FFErr_incomplete_comment
- return FFTok_error
- }
-}
-
-func (ffl *FFLexer) lexString() FFTok {
- if ffl.captureAll {
- ffl.buf.Reset()
- err := ffl.reader.SliceString(&ffl.buf)
-
- if err != nil {
- ffl.BigError = err
- return FFTok_error
- }
-
- WriteJson(ffl.Output, ffl.buf.Bytes())
-
- return FFTok_string
- } else {
- err := ffl.reader.SliceString(ffl.Output)
-
- if err != nil {
- ffl.BigError = err
- return FFTok_error
- }
-
- return FFTok_string
- }
-}
-
-func (ffl *FFLexer) lexNumber() FFTok {
- var numRead int = 0
- tok := FFTok_integer
-
- c, err := ffl.readByte()
- if err != nil {
- return FFTok_error
- }
-
- /* optional leading minus */
- if c == '-' {
- ffl.Output.WriteByte(c)
- c, err = ffl.readByte()
- if err != nil {
- return FFTok_error
- }
- }
-
- /* a single zero, or a series of integers */
- if c == '0' {
- ffl.Output.WriteByte(c)
- c, err = ffl.readByte()
- if err != nil {
- return FFTok_error
- }
- } else if c >= '1' && c <= '9' {
- for c >= '0' && c <= '9' {
- ffl.Output.WriteByte(c)
- c, err = ffl.readByte()
- if err != nil {
- return FFTok_error
- }
- }
- } else {
- ffl.unreadByte()
- ffl.Error = FFErr_missing_integer_after_minus
- return FFTok_error
- }
-
- if c == '.' {
- numRead = 0
- ffl.Output.WriteByte(c)
- c, err = ffl.readByte()
- if err != nil {
- return FFTok_error
- }
-
- for c >= '0' && c <= '9' {
- ffl.Output.WriteByte(c)
- numRead++
- c, err = ffl.readByte()
- if err != nil {
- return FFTok_error
- }
- }
-
- if numRead == 0 {
- ffl.unreadByte()
-
- ffl.Error = FFErr_missing_integer_after_decimal
- return FFTok_error
- }
-
- tok = FFTok_double
- }
-
- /* optional exponent (indicates this is floating point) */
- if c == 'e' || c == 'E' {
- numRead = 0
- ffl.Output.WriteByte(c)
-
- c, err = ffl.readByte()
- if err != nil {
- return FFTok_error
- }
-
- /* optional sign */
- if c == '+' || c == '-' {
- ffl.Output.WriteByte(c)
- c, err = ffl.readByte()
- if err != nil {
- return FFTok_error
- }
- }
-
- for c >= '0' && c <= '9' {
- ffl.Output.WriteByte(c)
- numRead++
- c, err = ffl.readByte()
- if err != nil {
- return FFTok_error
- }
- }
-
- if numRead == 0 {
- ffl.Error = FFErr_missing_integer_after_exponent
- return FFTok_error
- }
-
- tok = FFTok_double
- }
-
- ffl.unreadByte()
-
- return tok
-}
-
-var true_bytes = []byte{'r', 'u', 'e'}
-var false_bytes = []byte{'a', 'l', 's', 'e'}
-var null_bytes = []byte{'u', 'l', 'l'}
-
-func (ffl *FFLexer) Scan() FFTok {
- tok := FFTok_error
- if ffl.captureAll == false {
- ffl.Output.Reset()
- }
- ffl.Token = FFTok_init
-
- for {
- c, err := ffl.scanReadByte()
- if err != nil {
- if err == io.EOF {
- return FFTok_eof
- } else {
- return FFTok_error
- }
- }
-
- switch c {
- case '{':
- tok = FFTok_left_bracket
- if ffl.captureAll {
- ffl.Output.WriteByte('{')
- }
- goto lexed
- case '}':
- tok = FFTok_right_bracket
- if ffl.captureAll {
- ffl.Output.WriteByte('}')
- }
- goto lexed
- case '[':
- tok = FFTok_left_brace
- if ffl.captureAll {
- ffl.Output.WriteByte('[')
- }
- goto lexed
- case ']':
- tok = FFTok_right_brace
- if ffl.captureAll {
- ffl.Output.WriteByte(']')
- }
- goto lexed
- case ',':
- tok = FFTok_comma
- if ffl.captureAll {
- ffl.Output.WriteByte(',')
- }
- goto lexed
- case ':':
- tok = FFTok_colon
- if ffl.captureAll {
- ffl.Output.WriteByte(':')
- }
- goto lexed
- case '\t', '\n', '\v', '\f', '\r', ' ':
- if ffl.captureAll {
- ffl.Output.WriteByte(c)
- }
- break
- case 't':
- ffl.Output.WriteByte('t')
- tok = ffl.wantBytes(true_bytes, FFTok_bool)
- goto lexed
- case 'f':
- ffl.Output.WriteByte('f')
- tok = ffl.wantBytes(false_bytes, FFTok_bool)
- goto lexed
- case 'n':
- ffl.Output.WriteByte('n')
- tok = ffl.wantBytes(null_bytes, FFTok_null)
- goto lexed
- case '"':
- tok = ffl.lexString()
- goto lexed
- case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
- ffl.unreadByte()
- tok = ffl.lexNumber()
- goto lexed
- case '/':
- tok = ffl.lexComment()
- goto lexed
- default:
- tok = FFTok_error
- ffl.Error = FFErr_invalid_char
- }
- }
-
-lexed:
- ffl.Token = tok
- return tok
-}
-
-func (ffl *FFLexer) scanField(start FFTok, capture bool) ([]byte, error) {
- switch start {
- case FFTok_left_brace,
- FFTok_left_bracket:
- {
- end := FFTok_right_brace
- if start == FFTok_left_bracket {
- end = FFTok_right_bracket
- if capture {
- ffl.Output.WriteByte('{')
- }
- } else {
- if capture {
- ffl.Output.WriteByte('[')
- }
- }
-
- depth := 1
- if capture {
- ffl.captureAll = true
- }
- // TODO: work.
- scanloop:
- for {
- tok := ffl.Scan()
- //fmt.Printf("capture-token: %v end: %v depth: %v\n", tok, end, depth)
- switch tok {
- case FFTok_eof:
- return nil, errors.New("ffjson: unexpected EOF")
- case FFTok_error:
- if ffl.BigError != nil {
- return nil, ffl.BigError
- }
- return nil, ffl.Error.ToError()
- case end:
- depth--
- if depth == 0 {
- break scanloop
- }
- case start:
- depth++
- }
- }
-
- if capture {
- ffl.captureAll = false
- }
-
- if capture {
- return ffl.Output.Bytes(), nil
- } else {
- return nil, nil
- }
- }
- case FFTok_bool,
- FFTok_integer,
- FFTok_null,
- FFTok_double:
- // simple value, return it.
- if capture {
- return ffl.Output.Bytes(), nil
- } else {
- return nil, nil
- }
-
- case FFTok_string:
- //TODO(pquerna): so, other users expect this to be a quoted string :(
- if capture {
- ffl.buf.Reset()
- WriteJson(&ffl.buf, ffl.Output.Bytes())
- return ffl.buf.Bytes(), nil
- } else {
- return nil, nil
- }
-
- default:
- return nil, fmt.Errorf("ffjson: invalid capture type: %v", start)
- }
- panic("not reached")
-}
-
-// Captures an entire field value, including recursive objects,
-// and converts them to a []byte suitable to pass to a sub-object's
-// UnmarshalJSON
-func (ffl *FFLexer) CaptureField(start FFTok) ([]byte, error) {
- return ffl.scanField(start, true)
-}
-
-func (ffl *FFLexer) SkipField(start FFTok) error {
- _, err := ffl.scanField(start, false)
- return err
-}
-
-// TODO(pquerna): return line number and offset.
-func (err FFErr) ToError() error {
- switch err {
- case FFErr_e_ok:
- return nil
- case FFErr_io:
- return errors.New("ffjson: IO error")
- case FFErr_string_invalid_utf8:
- return errors.New("ffjson: string with invalid UTF-8 sequence")
- case FFErr_string_invalid_escaped_char:
- return errors.New("ffjson: string with invalid escaped character")
- case FFErr_string_invalid_json_char:
- return errors.New("ffjson: string with invalid JSON character")
- case FFErr_string_invalid_hex_char:
- return errors.New("ffjson: string with invalid hex character")
- case FFErr_invalid_char:
- return errors.New("ffjson: invalid character")
- case FFErr_invalid_string:
- return errors.New("ffjson: invalid string")
- case FFErr_missing_integer_after_decimal:
- return errors.New("ffjson: missing integer after decimal")
- case FFErr_missing_integer_after_exponent:
- return errors.New("ffjson: missing integer after exponent")
- case FFErr_missing_integer_after_minus:
- return errors.New("ffjson: missing integer after minus")
- case FFErr_unallowed_comment:
- return errors.New("ffjson: unallowed comment")
- case FFErr_incomplete_comment:
- return errors.New("ffjson: incomplete comment")
- case FFErr_unexpected_token_type:
- return errors.New("ffjson: unexpected token sequence")
- }
-
- panic(fmt.Sprintf("unknown error type: %v ", err))
-}
-
-func (state FFParseState) String() string {
- switch state {
- case FFParse_map_start:
- return "map:start"
- case FFParse_want_key:
- return "want_key"
- case FFParse_want_colon:
- return "want_colon"
- case FFParse_want_value:
- return "want_value"
- case FFParse_after_value:
- return "after_value"
- }
-
- panic(fmt.Sprintf("unknown parse state: %d", int(state)))
-}
-
-func (tok FFTok) String() string {
- switch tok {
- case FFTok_init:
- return "tok:init"
- case FFTok_bool:
- return "tok:bool"
- case FFTok_colon:
- return "tok:colon"
- case FFTok_comma:
- return "tok:comma"
- case FFTok_eof:
- return "tok:eof"
- case FFTok_error:
- return "tok:error"
- case FFTok_left_brace:
- return "tok:left_brace"
- case FFTok_left_bracket:
- return "tok:left_bracket"
- case FFTok_null:
- return "tok:null"
- case FFTok_right_brace:
- return "tok:right_brace"
- case FFTok_right_bracket:
- return "tok:right_bracket"
- case FFTok_integer:
- return "tok:integer"
- case FFTok_double:
- return "tok:double"
- case FFTok_string:
- return "tok:string"
- case FFTok_comment:
- return "comment"
- }
-
- panic(fmt.Sprintf("unknown token: %d", int(tok)))
-}
-
-/* a lookup table which lets us quickly determine three things:
- * cVEC - valid escaped control char
- * note. the solidus '/' may be escaped or not.
- * cIJC - invalid json char
- * cVHC - valid hex char
- * cNFP - needs further processing (from a string scanning perspective)
- * cNUC - needs utf8 checking when enabled (from a string scanning perspective)
- */
-
-const (
- cVEC int8 = 0x01
- cIJC int8 = 0x02
- cVHC int8 = 0x04
- cNFP int8 = 0x08
- cNUC int8 = 0x10
-)
-
-var byteLookupTable [256]int8 = [256]int8{
- cIJC, /* 0 */
- cIJC, /* 1 */
- cIJC, /* 2 */
- cIJC, /* 3 */
- cIJC, /* 4 */
- cIJC, /* 5 */
- cIJC, /* 6 */
- cIJC, /* 7 */
- cIJC, /* 8 */
- cIJC, /* 9 */
- cIJC, /* 10 */
- cIJC, /* 11 */
- cIJC, /* 12 */
- cIJC, /* 13 */
- cIJC, /* 14 */
- cIJC, /* 15 */
- cIJC, /* 16 */
- cIJC, /* 17 */
- cIJC, /* 18 */
- cIJC, /* 19 */
- cIJC, /* 20 */
- cIJC, /* 21 */
- cIJC, /* 22 */
- cIJC, /* 23 */
- cIJC, /* 24 */
- cIJC, /* 25 */
- cIJC, /* 26 */
- cIJC, /* 27 */
- cIJC, /* 28 */
- cIJC, /* 29 */
- cIJC, /* 30 */
- cIJC, /* 31 */
- 0, /* 32 */
- 0, /* 33 */
- cVEC | cIJC | cNFP, /* 34 */
- 0, /* 35 */
- 0, /* 36 */
- 0, /* 37 */
- 0, /* 38 */
- 0, /* 39 */
- 0, /* 40 */
- 0, /* 41 */
- 0, /* 42 */
- 0, /* 43 */
- 0, /* 44 */
- 0, /* 45 */
- 0, /* 46 */
- cVEC, /* 47 */
- cVHC, /* 48 */
- cVHC, /* 49 */
- cVHC, /* 50 */
- cVHC, /* 51 */
- cVHC, /* 52 */
- cVHC, /* 53 */
- cVHC, /* 54 */
- cVHC, /* 55 */
- cVHC, /* 56 */
- cVHC, /* 57 */
- 0, /* 58 */
- 0, /* 59 */
- 0, /* 60 */
- 0, /* 61 */
- 0, /* 62 */
- 0, /* 63 */
- 0, /* 64 */
- cVHC, /* 65 */
- cVHC, /* 66 */
- cVHC, /* 67 */
- cVHC, /* 68 */
- cVHC, /* 69 */
- cVHC, /* 70 */
- 0, /* 71 */
- 0, /* 72 */
- 0, /* 73 */
- 0, /* 74 */
- 0, /* 75 */
- 0, /* 76 */
- 0, /* 77 */
- 0, /* 78 */
- 0, /* 79 */
- 0, /* 80 */
- 0, /* 81 */
- 0, /* 82 */
- 0, /* 83 */
- 0, /* 84 */
- 0, /* 85 */
- 0, /* 86 */
- 0, /* 87 */
- 0, /* 88 */
- 0, /* 89 */
- 0, /* 90 */
- 0, /* 91 */
- cVEC | cIJC | cNFP, /* 92 */
- 0, /* 93 */
- 0, /* 94 */
- 0, /* 95 */
- 0, /* 96 */
- cVHC, /* 97 */
- cVEC | cVHC, /* 98 */
- cVHC, /* 99 */
- cVHC, /* 100 */
- cVHC, /* 101 */
- cVEC | cVHC, /* 102 */
- 0, /* 103 */
- 0, /* 104 */
- 0, /* 105 */
- 0, /* 106 */
- 0, /* 107 */
- 0, /* 108 */
- 0, /* 109 */
- cVEC, /* 110 */
- 0, /* 111 */
- 0, /* 112 */
- 0, /* 113 */
- cVEC, /* 114 */
- 0, /* 115 */
- cVEC, /* 116 */
- 0, /* 117 */
- 0, /* 118 */
- 0, /* 119 */
- 0, /* 120 */
- 0, /* 121 */
- 0, /* 122 */
- 0, /* 123 */
- 0, /* 124 */
- 0, /* 125 */
- 0, /* 126 */
- 0, /* 127 */
- cNUC, /* 128 */
- cNUC, /* 129 */
- cNUC, /* 130 */
- cNUC, /* 131 */
- cNUC, /* 132 */
- cNUC, /* 133 */
- cNUC, /* 134 */
- cNUC, /* 135 */
- cNUC, /* 136 */
- cNUC, /* 137 */
- cNUC, /* 138 */
- cNUC, /* 139 */
- cNUC, /* 140 */
- cNUC, /* 141 */
- cNUC, /* 142 */
- cNUC, /* 143 */
- cNUC, /* 144 */
- cNUC, /* 145 */
- cNUC, /* 146 */
- cNUC, /* 147 */
- cNUC, /* 148 */
- cNUC, /* 149 */
- cNUC, /* 150 */
- cNUC, /* 151 */
- cNUC, /* 152 */
- cNUC, /* 153 */
- cNUC, /* 154 */
- cNUC, /* 155 */
- cNUC, /* 156 */
- cNUC, /* 157 */
- cNUC, /* 158 */
- cNUC, /* 159 */
- cNUC, /* 160 */
- cNUC, /* 161 */
- cNUC, /* 162 */
- cNUC, /* 163 */
- cNUC, /* 164 */
- cNUC, /* 165 */
- cNUC, /* 166 */
- cNUC, /* 167 */
- cNUC, /* 168 */
- cNUC, /* 169 */
- cNUC, /* 170 */
- cNUC, /* 171 */
- cNUC, /* 172 */
- cNUC, /* 173 */
- cNUC, /* 174 */
- cNUC, /* 175 */
- cNUC, /* 176 */
- cNUC, /* 177 */
- cNUC, /* 178 */
- cNUC, /* 179 */
- cNUC, /* 180 */
- cNUC, /* 181 */
- cNUC, /* 182 */
- cNUC, /* 183 */
- cNUC, /* 184 */
- cNUC, /* 185 */
- cNUC, /* 186 */
- cNUC, /* 187 */
- cNUC, /* 188 */
- cNUC, /* 189 */
- cNUC, /* 190 */
- cNUC, /* 191 */
- cNUC, /* 192 */
- cNUC, /* 193 */
- cNUC, /* 194 */
- cNUC, /* 195 */
- cNUC, /* 196 */
- cNUC, /* 197 */
- cNUC, /* 198 */
- cNUC, /* 199 */
- cNUC, /* 200 */
- cNUC, /* 201 */
- cNUC, /* 202 */
- cNUC, /* 203 */
- cNUC, /* 204 */
- cNUC, /* 205 */
- cNUC, /* 206 */
- cNUC, /* 207 */
- cNUC, /* 208 */
- cNUC, /* 209 */
- cNUC, /* 210 */
- cNUC, /* 211 */
- cNUC, /* 212 */
- cNUC, /* 213 */
- cNUC, /* 214 */
- cNUC, /* 215 */
- cNUC, /* 216 */
- cNUC, /* 217 */
- cNUC, /* 218 */
- cNUC, /* 219 */
- cNUC, /* 220 */
- cNUC, /* 221 */
- cNUC, /* 222 */
- cNUC, /* 223 */
- cNUC, /* 224 */
- cNUC, /* 225 */
- cNUC, /* 226 */
- cNUC, /* 227 */
- cNUC, /* 228 */
- cNUC, /* 229 */
- cNUC, /* 230 */
- cNUC, /* 231 */
- cNUC, /* 232 */
- cNUC, /* 233 */
- cNUC, /* 234 */
- cNUC, /* 235 */
- cNUC, /* 236 */
- cNUC, /* 237 */
- cNUC, /* 238 */
- cNUC, /* 239 */
- cNUC, /* 240 */
- cNUC, /* 241 */
- cNUC, /* 242 */
- cNUC, /* 243 */
- cNUC, /* 244 */
- cNUC, /* 245 */
- cNUC, /* 246 */
- cNUC, /* 247 */
- cNUC, /* 248 */
- cNUC, /* 249 */
- cNUC, /* 250 */
- cNUC, /* 251 */
- cNUC, /* 252 */
- cNUC, /* 253 */
- cNUC, /* 254 */
- cNUC, /* 255 */
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/reader.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/reader.go
deleted file mode 100644
index f3d3c407..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/reader.go
+++ /dev/null
@@ -1,509 +0,0 @@
-/**
- * Copyright 2014 Paul Querna
- *
- * 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 v1
-
-import (
- "fmt"
- "io"
- "unicode"
- "unicode/utf16"
-)
-
-const sliceStringMask = cIJC | cNFP
-
-type ffReader struct {
- s []byte
- i int
- l int
-}
-
-func newffReader(d []byte) *ffReader {
- return &ffReader{
- s: d,
- i: 0,
- l: len(d),
- }
-}
-
-func (r *ffReader) Pos() int {
- return r.i
-}
-
-// Reset the reader, and add new input.
-func (r *ffReader) Reset(d []byte) {
- r.s = d
- r.i = 0
- r.l = len(d)
-}
-
-// Calcuates the Position with line and line offset,
-// because this isn't counted for performance reasons,
-// it will iterate the buffer from the beginning, and should
-// only be used in error-paths.
-func (r *ffReader) PosWithLine() (int, int) {
- currentLine := 1
- currentChar := 0
-
- for i := 0; i < r.i; i++ {
- c := r.s[i]
- currentChar++
- if c == '\n' {
- currentLine++
- currentChar = 0
- }
- }
-
- return currentLine, currentChar
-}
-
-func (r *ffReader) ReadByteNoWS() (byte, error) {
- if r.i >= r.l {
- return 0, io.EOF
- }
-
- j := r.i
-
- for {
- c := r.s[j]
- j++
-
- // inline whitespace parsing gives another ~8% performance boost
- // for many kinds of nicely indented JSON.
- // ... and using a [255]bool instead of multiple ifs, gives another 2%
- /*
- if c != '\t' &&
- c != '\n' &&
- c != '\v' &&
- c != '\f' &&
- c != '\r' &&
- c != ' ' {
- r.i = j
- return c, nil
- }
- */
- if whitespaceLookupTable[c] == false {
- r.i = j
- return c, nil
- }
-
- if j >= r.l {
- return 0, io.EOF
- }
- }
-}
-
-func (r *ffReader) ReadByte() (byte, error) {
- if r.i >= r.l {
- return 0, io.EOF
- }
-
- r.i++
-
- return r.s[r.i-1], nil
-}
-
-func (r *ffReader) UnreadByte() {
- if r.i <= 0 {
- panic("ffReader.UnreadByte: at beginning of slice")
- }
- r.i--
-}
-
-func (r *ffReader) readU4(j int) (rune, error) {
-
- var u4 [4]byte
- for i := 0; i < 4; i++ {
- if j >= r.l {
- return -1, io.EOF
- }
- c := r.s[j]
- if byteLookupTable[c]&cVHC != 0 {
- u4[i] = c
- j++
- continue
- } else {
- // TODO(pquerna): handle errors better. layering violation.
- return -1, fmt.Errorf("lex_string_invalid_hex_char: %v %v", c, string(u4[:]))
- }
- }
-
- // TODO(pquerna): utf16.IsSurrogate
- rr, err := ParseUint(u4[:], 16, 64)
- if err != nil {
- return -1, err
- }
- return rune(rr), nil
-}
-
-func (r *ffReader) handleEscaped(c byte, j int, out DecodingBuffer) (int, error) {
- if j >= r.l {
- return 0, io.EOF
- }
-
- c = r.s[j]
- j++
-
- if c == 'u' {
- ru, err := r.readU4(j)
- if err != nil {
- return 0, err
- }
-
- if utf16.IsSurrogate(ru) {
- ru2, err := r.readU4(j + 6)
- if err != nil {
- return 0, err
- }
- out.Write(r.s[r.i : j-2])
- r.i = j + 10
- j = r.i
- rval := utf16.DecodeRune(ru, ru2)
- if rval != unicode.ReplacementChar {
- out.WriteRune(rval)
- } else {
- return 0, fmt.Errorf("lex_string_invalid_unicode_surrogate: %v %v", ru, ru2)
- }
- } else {
- out.Write(r.s[r.i : j-2])
- r.i = j + 4
- j = r.i
- out.WriteRune(ru)
- }
- return j, nil
- } else if byteLookupTable[c]&cVEC == 0 {
- return 0, fmt.Errorf("lex_string_invalid_escaped_char: %v", c)
- } else {
- out.Write(r.s[r.i : j-2])
- r.i = j
- j = r.i
-
- switch c {
- case '"':
- out.WriteByte('"')
- case '\\':
- out.WriteByte('\\')
- case '/':
- out.WriteByte('/')
- case 'b':
- out.WriteByte('\b')
- case 'f':
- out.WriteByte('\f')
- case 'n':
- out.WriteByte('\n')
- case 'r':
- out.WriteByte('\r')
- case 't':
- out.WriteByte('\t')
- }
- }
-
- return j, nil
-}
-
-func (r *ffReader) SliceString(out DecodingBuffer) error {
- var c byte
- // TODO(pquerna): string_with_escapes? de-escape here?
- j := r.i
-
- for {
- if j >= r.l {
- return io.EOF
- }
-
- j, c = scanString(r.s, j)
-
- if c == '"' {
- if j != r.i {
- out.Write(r.s[r.i : j-1])
- r.i = j
- }
- return nil
- } else if c == '\\' {
- var err error
- j, err = r.handleEscaped(c, j, out)
- if err != nil {
- return err
- }
- } else if byteLookupTable[c]&cIJC != 0 {
- return fmt.Errorf("lex_string_invalid_json_char: %v", c)
- }
- continue
- }
-
- panic("ffjson: SliceString unreached exit")
-}
-
-// TODO(pquerna): consider combining wibth the normal byte mask.
-var whitespaceLookupTable [256]bool = [256]bool{
- false, /* 0 */
- false, /* 1 */
- false, /* 2 */
- false, /* 3 */
- false, /* 4 */
- false, /* 5 */
- false, /* 6 */
- false, /* 7 */
- false, /* 8 */
- true, /* 9 */
- true, /* 10 */
- true, /* 11 */
- true, /* 12 */
- true, /* 13 */
- false, /* 14 */
- false, /* 15 */
- false, /* 16 */
- false, /* 17 */
- false, /* 18 */
- false, /* 19 */
- false, /* 20 */
- false, /* 21 */
- false, /* 22 */
- false, /* 23 */
- false, /* 24 */
- false, /* 25 */
- false, /* 26 */
- false, /* 27 */
- false, /* 28 */
- false, /* 29 */
- false, /* 30 */
- false, /* 31 */
- true, /* 32 */
- false, /* 33 */
- false, /* 34 */
- false, /* 35 */
- false, /* 36 */
- false, /* 37 */
- false, /* 38 */
- false, /* 39 */
- false, /* 40 */
- false, /* 41 */
- false, /* 42 */
- false, /* 43 */
- false, /* 44 */
- false, /* 45 */
- false, /* 46 */
- false, /* 47 */
- false, /* 48 */
- false, /* 49 */
- false, /* 50 */
- false, /* 51 */
- false, /* 52 */
- false, /* 53 */
- false, /* 54 */
- false, /* 55 */
- false, /* 56 */
- false, /* 57 */
- false, /* 58 */
- false, /* 59 */
- false, /* 60 */
- false, /* 61 */
- false, /* 62 */
- false, /* 63 */
- false, /* 64 */
- false, /* 65 */
- false, /* 66 */
- false, /* 67 */
- false, /* 68 */
- false, /* 69 */
- false, /* 70 */
- false, /* 71 */
- false, /* 72 */
- false, /* 73 */
- false, /* 74 */
- false, /* 75 */
- false, /* 76 */
- false, /* 77 */
- false, /* 78 */
- false, /* 79 */
- false, /* 80 */
- false, /* 81 */
- false, /* 82 */
- false, /* 83 */
- false, /* 84 */
- false, /* 85 */
- false, /* 86 */
- false, /* 87 */
- false, /* 88 */
- false, /* 89 */
- false, /* 90 */
- false, /* 91 */
- false, /* 92 */
- false, /* 93 */
- false, /* 94 */
- false, /* 95 */
- false, /* 96 */
- false, /* 97 */
- false, /* 98 */
- false, /* 99 */
- false, /* 100 */
- false, /* 101 */
- false, /* 102 */
- false, /* 103 */
- false, /* 104 */
- false, /* 105 */
- false, /* 106 */
- false, /* 107 */
- false, /* 108 */
- false, /* 109 */
- false, /* 110 */
- false, /* 111 */
- false, /* 112 */
- false, /* 113 */
- false, /* 114 */
- false, /* 115 */
- false, /* 116 */
- false, /* 117 */
- false, /* 118 */
- false, /* 119 */
- false, /* 120 */
- false, /* 121 */
- false, /* 122 */
- false, /* 123 */
- false, /* 124 */
- false, /* 125 */
- false, /* 126 */
- false, /* 127 */
- false, /* 128 */
- false, /* 129 */
- false, /* 130 */
- false, /* 131 */
- false, /* 132 */
- false, /* 133 */
- false, /* 134 */
- false, /* 135 */
- false, /* 136 */
- false, /* 137 */
- false, /* 138 */
- false, /* 139 */
- false, /* 140 */
- false, /* 141 */
- false, /* 142 */
- false, /* 143 */
- false, /* 144 */
- false, /* 145 */
- false, /* 146 */
- false, /* 147 */
- false, /* 148 */
- false, /* 149 */
- false, /* 150 */
- false, /* 151 */
- false, /* 152 */
- false, /* 153 */
- false, /* 154 */
- false, /* 155 */
- false, /* 156 */
- false, /* 157 */
- false, /* 158 */
- false, /* 159 */
- false, /* 160 */
- false, /* 161 */
- false, /* 162 */
- false, /* 163 */
- false, /* 164 */
- false, /* 165 */
- false, /* 166 */
- false, /* 167 */
- false, /* 168 */
- false, /* 169 */
- false, /* 170 */
- false, /* 171 */
- false, /* 172 */
- false, /* 173 */
- false, /* 174 */
- false, /* 175 */
- false, /* 176 */
- false, /* 177 */
- false, /* 178 */
- false, /* 179 */
- false, /* 180 */
- false, /* 181 */
- false, /* 182 */
- false, /* 183 */
- false, /* 184 */
- false, /* 185 */
- false, /* 186 */
- false, /* 187 */
- false, /* 188 */
- false, /* 189 */
- false, /* 190 */
- false, /* 191 */
- false, /* 192 */
- false, /* 193 */
- false, /* 194 */
- false, /* 195 */
- false, /* 196 */
- false, /* 197 */
- false, /* 198 */
- false, /* 199 */
- false, /* 200 */
- false, /* 201 */
- false, /* 202 */
- false, /* 203 */
- false, /* 204 */
- false, /* 205 */
- false, /* 206 */
- false, /* 207 */
- false, /* 208 */
- false, /* 209 */
- false, /* 210 */
- false, /* 211 */
- false, /* 212 */
- false, /* 213 */
- false, /* 214 */
- false, /* 215 */
- false, /* 216 */
- false, /* 217 */
- false, /* 218 */
- false, /* 219 */
- false, /* 220 */
- false, /* 221 */
- false, /* 222 */
- false, /* 223 */
- false, /* 224 */
- false, /* 225 */
- false, /* 226 */
- false, /* 227 */
- false, /* 228 */
- false, /* 229 */
- false, /* 230 */
- false, /* 231 */
- false, /* 232 */
- false, /* 233 */
- false, /* 234 */
- false, /* 235 */
- false, /* 236 */
- false, /* 237 */
- false, /* 238 */
- false, /* 239 */
- false, /* 240 */
- false, /* 241 */
- false, /* 242 */
- false, /* 243 */
- false, /* 244 */
- false, /* 245 */
- false, /* 246 */
- false, /* 247 */
- false, /* 248 */
- false, /* 249 */
- false, /* 250 */
- false, /* 251 */
- false, /* 252 */
- false, /* 253 */
- false, /* 254 */
- false, /* 255 */
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/reader_scan_amd64.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/reader_scan_amd64.go
deleted file mode 100644
index f94d55f4..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/reader_scan_amd64.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// +build amd64
-// +build !appengine
-
-/**
- * Copyright 2014 Paul Querna
- *
- * 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 v1
-
-func haveSSE42() bool
-func scanStringSSE(s []byte, j int) (int, byte)
-
-var sse42 = haveSSE42()
-
-func scanString(s []byte, j int) (int, byte) {
- // XXX The following fails to compile on Go 1.2.
- /*
- if false && sse42 {
- return scanStringSSE(s, j)
- }
- */
-
- for {
- if j >= len(s) {
- return j, 0
- }
-
- c := s[j]
- j++
- if byteLookupTable[c]&sliceStringMask == 0 {
- continue
- }
-
- return j, c
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/reader_scan_amd64.s b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/reader_scan_amd64.s
deleted file mode 100644
index f76fb982..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/reader_scan_amd64.s
+++ /dev/null
@@ -1,22 +0,0 @@
-// +build !appengine
-
-#define NOSPLIT 4
-
-// func scanStringSSE(s []byte, j int) (int, byte)
-TEXT scanStringSSE(SB),NOSPLIT,$0
- // TODO: http://www.strchr.com/strcmp_and_strlen_using_sse_4.2
- // Equal any, operand1 set to
- RET
-
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// func haveSSE42() bool
-TEXT ·haveSSE42(SB),NOSPLIT,$0
- XORQ AX, AX
- INCL AX
- CPUID
- SHRQ $20, CX
- ANDQ $1, CX
- MOVB CX, ret+0(FP)
- RET
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/reader_scan_generic.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/reader_scan_generic.go
deleted file mode 100644
index 4f4ce638..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/pquerna/ffjson/fflib/v1/reader_scan_generic.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// +build !amd64 appengine
-
-/**
- * Copyright 2014 Paul Querna
- *
- * 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 v1
-
-func scanString(s []byte, j int) (int, byte) {
- for {
- if j >= len(s) {
- return j, 0
- }
-
- c := s[j]
- j++
- if byteLookupTable[c]&sliceStringMask == 0 {
- continue
- }
-
- return j, c
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/seccomp/libseccomp-golang/LICENSE b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/seccomp/libseccomp-golang/LICENSE
deleted file mode 100644
index 81cf60de..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/seccomp/libseccomp-golang/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2015 Matthew Heon
-Copyright (c) 2015 Paul Moore
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/seccomp/libseccomp-golang/README b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/seccomp/libseccomp-golang/README
deleted file mode 100644
index 64cab691..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/seccomp/libseccomp-golang/README
+++ /dev/null
@@ -1,26 +0,0 @@
-libseccomp-golang: Go Language Bindings for the libseccomp Project
-===============================================================================
-https://github.com/seccomp/libseccomp-golang
-https://github.com/seccomp/libseccomp
-
-The libseccomp library provides an easy to use, platform independent, interface
-to the Linux Kernel's syscall filtering mechanism. The libseccomp API is
-designed to abstract away the underlying BPF based syscall filter language and
-present a more conventional function-call based filtering interface that should
-be familiar to, and easily adopted by, application developers.
-
-The libseccomp-golang library provides a Go based interface to the libseccomp
-library.
-
-* Online Resources
-
-The library source repository currently lives on GitHub at the following URLs:
-
- -> https://github.com/seccomp/libseccomp-golang
- -> https://github.com/seccomp/libseccomp
-
-The project mailing list is currently hosted on Google Groups at the URL below,
-please note that a Google account is not required to subscribe to the mailing
-list.
-
- -> https://groups.google.com/d/forum/libseccomp
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/seccomp/libseccomp-golang/seccomp.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/seccomp/libseccomp-golang/seccomp.go
deleted file mode 100644
index cebafdfa..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/seccomp/libseccomp-golang/seccomp.go
+++ /dev/null
@@ -1,827 +0,0 @@
-// +build linux
-
-// Public API specification for libseccomp Go bindings
-// Contains public API for the bindings
-
-// Package seccomp rovides bindings for libseccomp, a library wrapping the Linux
-// seccomp syscall. Seccomp enables an application to restrict system call use
-// for itself and its children.
-package seccomp
-
-import (
- "fmt"
- "os"
- "runtime"
- "strings"
- "sync"
- "syscall"
- "unsafe"
-)
-
-// C wrapping code
-
-// #cgo LDFLAGS: -lseccomp
-// #include
-// #include
-import "C"
-
-// Exported types
-
-// ScmpArch represents a CPU architecture. Seccomp can restrict syscalls on a
-// per-architecture basis.
-type ScmpArch uint
-
-// ScmpAction represents an action to be taken on a filter rule match in
-// libseccomp
-type ScmpAction uint
-
-// ScmpCompareOp represents a comparison operator which can be used in a filter
-// rule
-type ScmpCompareOp uint
-
-// ScmpCondition represents a rule in a libseccomp filter context
-type ScmpCondition struct {
- Argument uint `json:"argument,omitempty"`
- Op ScmpCompareOp `json:"operator,omitempty"`
- Operand1 uint64 `json:"operand_one,omitempty"`
- Operand2 uint64 `json:"operand_two,omitempty"`
-}
-
-// ScmpSyscall represents a Linux System Call
-type ScmpSyscall int32
-
-// Exported Constants
-
-const (
- // Valid architectures recognized by libseccomp
- // ARM64 and all MIPS architectures are unsupported by versions of the
- // library before v2.2 and will return errors if used
-
- // ArchInvalid is a placeholder to ensure uninitialized ScmpArch
- // variables are invalid
- ArchInvalid ScmpArch = iota
- // ArchNative is the native architecture of the kernel
- ArchNative ScmpArch = iota
- // ArchX86 represents 32-bit x86 syscalls
- ArchX86 ScmpArch = iota
- // ArchAMD64 represents 64-bit x86-64 syscalls
- ArchAMD64 ScmpArch = iota
- // ArchX32 represents 64-bit x86-64 syscalls (32-bit pointers)
- ArchX32 ScmpArch = iota
- // ArchARM represents 32-bit ARM syscalls
- ArchARM ScmpArch = iota
- // ArchARM64 represents 64-bit ARM syscalls
- ArchARM64 ScmpArch = iota
- // ArchMIPS represents 32-bit MIPS syscalls
- ArchMIPS ScmpArch = iota
- // ArchMIPS64 represents 64-bit MIPS syscalls
- ArchMIPS64 ScmpArch = iota
- // ArchMIPS64N32 represents 64-bit MIPS syscalls (32-bit pointers)
- ArchMIPS64N32 ScmpArch = iota
- // ArchMIPSEL represents 32-bit MIPS syscalls (little endian)
- ArchMIPSEL ScmpArch = iota
- // ArchMIPSEL64 represents 64-bit MIPS syscalls (little endian)
- ArchMIPSEL64 ScmpArch = iota
- // ArchMIPSEL64N32 represents 64-bit MIPS syscalls (little endian,
- // 32-bit pointers)
- ArchMIPSEL64N32 ScmpArch = iota
-)
-
-const (
- // Supported actions on filter match
-
- // ActInvalid is a placeholder to ensure uninitialized ScmpAction
- // variables are invalid
- ActInvalid ScmpAction = iota
- // ActKill kills the process
- ActKill ScmpAction = iota
- // ActTrap throws SIGSYS
- ActTrap ScmpAction = iota
- // ActErrno causes the syscall to return a negative error code. This
- // code can be set with the SetReturnCode method
- ActErrno ScmpAction = iota
- // ActTrace causes the syscall to notify tracing processes with the
- // given error code. This code can be set with the SetReturnCode method
- ActTrace ScmpAction = iota
- // ActAllow permits the syscall to continue execution
- ActAllow ScmpAction = iota
-)
-
-const (
- // These are comparison operators used in conditional seccomp rules
- // They are used to compare the value of a single argument of a syscall
- // against a user-defined constant
-
- // CompareInvalid is a placeholder to ensure uninitialized ScmpCompareOp
- // variables are invalid
- CompareInvalid ScmpCompareOp = iota
- // CompareNotEqual returns true if the argument is not equal to the
- // given value
- CompareNotEqual ScmpCompareOp = iota
- // CompareLess returns true if the argument is less than the given value
- CompareLess ScmpCompareOp = iota
- // CompareLessOrEqual returns true if the argument is less than or equal
- // to the given value
- CompareLessOrEqual ScmpCompareOp = iota
- // CompareEqual returns true if the argument is equal to the given value
- CompareEqual ScmpCompareOp = iota
- // CompareGreaterEqual returns true if the argument is greater than or
- // equal to the given value
- CompareGreaterEqual ScmpCompareOp = iota
- // CompareGreater returns true if the argument is greater than the given
- // value
- CompareGreater ScmpCompareOp = iota
- // CompareMaskedEqual returns true if the argument is equal to the given
- // value, when masked (bitwise &) against the second given value
- CompareMaskedEqual ScmpCompareOp = iota
-)
-
-// Helpers for types
-
-// GetArchFromString returns an ScmpArch constant from a string representing an
-// architecture
-func GetArchFromString(arch string) (ScmpArch, error) {
- switch strings.ToLower(arch) {
- case "x86":
- return ArchX86, nil
- case "amd64", "x86-64", "x86_64", "x64":
- return ArchAMD64, nil
- case "x32":
- return ArchX32, nil
- case "arm":
- return ArchARM, nil
- case "arm64", "aarch64":
- return ArchARM64, nil
- case "mips":
- return ArchMIPS, nil
- case "mips64":
- return ArchMIPS64, nil
- case "mips64n32":
- return ArchMIPS64N32, nil
- case "mipsel":
- return ArchMIPSEL, nil
- case "mipsel64":
- return ArchMIPSEL64, nil
- case "mipsel64n32":
- return ArchMIPSEL64N32, nil
- default:
- return ArchInvalid, fmt.Errorf("cannot convert unrecognized string %s", arch)
- }
-}
-
-// String returns a string representation of an architecture constant
-func (a ScmpArch) String() string {
- switch a {
- case ArchX86:
- return "x86"
- case ArchAMD64:
- return "amd64"
- case ArchX32:
- return "x32"
- case ArchARM:
- return "arm"
- case ArchARM64:
- return "arm64"
- case ArchMIPS:
- return "mips"
- case ArchMIPS64:
- return "mips64"
- case ArchMIPS64N32:
- return "mips64n32"
- case ArchMIPSEL:
- return "mipsel"
- case ArchMIPSEL64:
- return "mipsel64"
- case ArchMIPSEL64N32:
- return "mipsel64n32"
- case ArchNative:
- return "native"
- case ArchInvalid:
- return "Invalid architecture"
- default:
- return "Unknown architecture"
- }
-}
-
-// String returns a string representation of a comparison operator constant
-func (a ScmpCompareOp) String() string {
- switch a {
- case CompareNotEqual:
- return "Not equal"
- case CompareLess:
- return "Less than"
- case CompareLessOrEqual:
- return "Less than or equal to"
- case CompareEqual:
- return "Equal"
- case CompareGreaterEqual:
- return "Greater than or equal to"
- case CompareGreater:
- return "Greater than"
- case CompareMaskedEqual:
- return "Masked equality"
- case CompareInvalid:
- return "Invalid comparison operator"
- default:
- return "Unrecognized comparison operator"
- }
-}
-
-// String returns a string representation of a seccomp match action
-func (a ScmpAction) String() string {
- switch a & 0xFFFF {
- case ActKill:
- return "Action: Kill Process"
- case ActTrap:
- return "Action: Send SIGSYS"
- case ActErrno:
- return fmt.Sprintf("Action: Return error code %d", (a >> 16))
- case ActTrace:
- return fmt.Sprintf("Action: Notify tracing processes with code %d",
- (a >> 16))
- case ActAllow:
- return "Action: Allow system call"
- default:
- return "Unrecognized Action"
- }
-}
-
-// SetReturnCode adds a return code to a supporting ScmpAction, clearing any
-// existing code Only valid on ActErrno and ActTrace. Takes no action otherwise.
-// Accepts 16-bit return code as argument.
-// Returns a valid ScmpAction of the original type with the new error code set.
-func (a ScmpAction) SetReturnCode(code int16) ScmpAction {
- aTmp := a & 0x0000FFFF
- if aTmp == ActErrno || aTmp == ActTrace {
- return (aTmp | (ScmpAction(code)&0xFFFF)<<16)
- }
- return a
-}
-
-// GetReturnCode returns the return code of an ScmpAction
-func (a ScmpAction) GetReturnCode() int16 {
- return int16(a >> 16)
-}
-
-// General utility functions
-
-// GetLibraryVersion returns the version of the library the bindings are built
-// against.
-// The version is formatted as follows: Major.Minor.Micro
-func GetLibraryVersion() (major, minor, micro int) {
- return verMajor, verMinor, verMicro
-}
-
-// Syscall functions
-
-// GetName retrieves the name of a syscall from its number.
-// Acts on any syscall number.
-// Returns either a string containing the name of the syscall, or an error.
-func (s ScmpSyscall) GetName() (string, error) {
- return s.GetNameByArch(ArchNative)
-}
-
-// GetNameByArch retrieves the name of a syscall from its number for a given
-// architecture.
-// Acts on any syscall number.
-// Accepts a valid architecture constant.
-// Returns either a string containing the name of the syscall, or an error.
-// if the syscall is unrecognized or an issue occurred.
-func (s ScmpSyscall) GetNameByArch(arch ScmpArch) (string, error) {
- if err := sanitizeArch(arch); err != nil {
- return "", err
- }
-
- cString := C.seccomp_syscall_resolve_num_arch(arch.toNative(), C.int(s))
- if cString == nil {
- return "", fmt.Errorf("could not resolve syscall name")
- }
- defer C.free(unsafe.Pointer(cString))
-
- finalStr := C.GoString(cString)
- return finalStr, nil
-}
-
-// GetSyscallFromName returns the number of a syscall by name on the kernel's
-// native architecture.
-// Accepts a string containing the name of a syscall.
-// Returns the number of the syscall, or an error if no syscall with that name
-// was found.
-func GetSyscallFromName(name string) (ScmpSyscall, error) {
- cString := C.CString(name)
- defer C.free(unsafe.Pointer(cString))
-
- result := C.seccomp_syscall_resolve_name(cString)
- if result == scmpError {
- return 0, fmt.Errorf("could not resolve name to syscall")
- }
-
- return ScmpSyscall(result), nil
-}
-
-// GetSyscallFromNameByArch returns the number of a syscall by name for a given
-// architecture's ABI.
-// Accepts the name of a syscall and an architecture constant.
-// Returns the number of the syscall, or an error if an invalid architecture is
-// passed or a syscall with that name was not found.
-func GetSyscallFromNameByArch(name string, arch ScmpArch) (ScmpSyscall, error) {
- if err := sanitizeArch(arch); err != nil {
- return 0, err
- }
-
- cString := C.CString(name)
- defer C.free(unsafe.Pointer(cString))
-
- result := C.seccomp_syscall_resolve_name_arch(arch.toNative(), cString)
- if result == scmpError {
- return 0, fmt.Errorf("could not resolve name to syscall")
- }
-
- return ScmpSyscall(result), nil
-}
-
-// MakeCondition creates and returns a new condition to attach to a filter rule.
-// Associated rules will only match if this condition is true.
-// Accepts the number the argument we are checking, and a comparison operator
-// and value to compare to.
-// The rule will match if argument $arg (zero-indexed) of the syscall is
-// $COMPARE_OP the provided comparison value.
-// Some comparison operators accept two values. Masked equals, for example,
-// will mask $arg of the syscall with the second value provided (via bitwise
-// AND) and then compare against the first value provided.
-// For example, in the less than or equal case, if the syscall argument was
-// 0 and the value provided was 1, the condition would match, as 0 is less
-// than or equal to 1.
-// Return either an error on bad argument or a valid ScmpCondition struct.
-func MakeCondition(arg uint, comparison ScmpCompareOp, values ...uint64) (ScmpCondition, error) {
- var condStruct ScmpCondition
-
- if comparison == CompareInvalid {
- return condStruct, fmt.Errorf("invalid comparison operator")
- } else if arg > 5 {
- return condStruct, fmt.Errorf("syscalls only have up to 6 arguments")
- } else if len(values) > 2 {
- return condStruct, fmt.Errorf("conditions can have at most 2 arguments")
- } else if len(values) == 0 {
- return condStruct, fmt.Errorf("must provide at least one value to compare against")
- }
-
- condStruct.Argument = arg
- condStruct.Op = comparison
- condStruct.Operand1 = values[0]
- if len(values) == 2 {
- condStruct.Operand2 = values[1]
- } else {
- condStruct.Operand2 = 0 // Unused
- }
-
- return condStruct, nil
-}
-
-// Utility Functions
-
-// GetNativeArch returns architecture token representing the native kernel
-// architecture
-func GetNativeArch() (ScmpArch, error) {
- arch := C.seccomp_arch_native()
-
- return archFromNative(arch)
-}
-
-// Public Filter API
-
-// ScmpFilter represents a filter context in libseccomp.
-// A filter context is initially empty. Rules can be added to it, and it can
-// then be loaded into the kernel.
-type ScmpFilter struct {
- filterCtx C.scmp_filter_ctx
- valid bool
- lock sync.Mutex
-}
-
-// NewFilter creates and returns a new filter context.
-// Accepts a default action to be taken for syscalls which match no rules in
-// the filter.
-// Returns a reference to a valid filter context, or nil and an error if the
-// filter context could not be created or an invalid default action was given.
-func NewFilter(defaultAction ScmpAction) (*ScmpFilter, error) {
- if err := sanitizeAction(defaultAction); err != nil {
- return nil, err
- }
-
- fPtr := C.seccomp_init(defaultAction.toNative())
- if fPtr == nil {
- return nil, fmt.Errorf("could not create filter")
- }
-
- filter := new(ScmpFilter)
- filter.filterCtx = fPtr
- filter.valid = true
- runtime.SetFinalizer(filter, filterFinalizer)
-
- return filter, nil
-}
-
-// IsValid determines whether a filter context is valid to use.
-// Some operations (Release and Merge) render filter contexts invalid and
-// consequently prevent further use.
-func (f *ScmpFilter) IsValid() bool {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- return f.valid
-}
-
-// Reset resets a filter context, removing all its existing state.
-// Accepts a new default action to be taken for syscalls which do not match.
-// Returns an error if the filter or action provided are invalid.
-func (f *ScmpFilter) Reset(defaultAction ScmpAction) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if err := sanitizeAction(defaultAction); err != nil {
- return err
- } else if !f.valid {
- return errBadFilter
- }
-
- retCode := C.seccomp_reset(f.filterCtx, defaultAction.toNative())
- if retCode != 0 {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
-
-// Release releases a filter context, freeing its memory. Should be called after
-// loading into the kernel, when the filter is no longer needed.
-// After calling this function, the given filter is no longer valid and cannot
-// be used.
-// Release() will be invoked automatically when a filter context is garbage
-// collected, but can also be called manually to free memory.
-func (f *ScmpFilter) Release() {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if !f.valid {
- return
- }
-
- f.valid = false
- C.seccomp_release(f.filterCtx)
-}
-
-// Merge merges two filter contexts.
-// The source filter src will be released as part of the process, and will no
-// longer be usable or valid after this call.
-// To be merged, filters must NOT share any architectures, and all their
-// attributes (Default Action, Bad Arch Action, No New Privs and TSync bools)
-// must match.
-// The filter src will be merged into the filter this is called on.
-// The architectures of the src filter not present in the destination, and all
-// associated rules, will be added to the destination.
-// Returns an error if merging the filters failed.
-func (f *ScmpFilter) Merge(src *ScmpFilter) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- src.lock.Lock()
- defer src.lock.Unlock()
-
- if !src.valid || !f.valid {
- return fmt.Errorf("one or more of the filter contexts is invalid or uninitialized")
- }
-
- // Merge the filters
- retCode := C.seccomp_merge(f.filterCtx, src.filterCtx)
- if syscall.Errno(-1*retCode) == syscall.EINVAL {
- return fmt.Errorf("filters could not be merged due to a mismatch in attributes or invalid filter")
- } else if retCode != 0 {
- return syscall.Errno(-1 * retCode)
- }
-
- src.valid = false
-
- return nil
-}
-
-// IsArchPresent checks if an architecture is present in a filter.
-// If a filter contains an architecture, it uses its default action for
-// syscalls which do not match rules in it, and its rules can match syscalls
-// for that ABI.
-// If a filter does not contain an architecture, all syscalls made to that
-// kernel ABI will fail with the filter's default Bad Architecture Action
-// (by default, killing the process).
-// Accepts an architecture constant.
-// Returns true if the architecture is present in the filter, false otherwise,
-// and an error on an invalid filter context, architecture constant, or an
-// issue with the call to libseccomp.
-func (f *ScmpFilter) IsArchPresent(arch ScmpArch) (bool, error) {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if err := sanitizeArch(arch); err != nil {
- return false, err
- } else if !f.valid {
- return false, errBadFilter
- }
-
- retCode := C.seccomp_arch_exist(f.filterCtx, arch.toNative())
- if syscall.Errno(-1*retCode) == syscall.EEXIST {
- // -EEXIST is "arch not present"
- return false, nil
- } else if retCode != 0 {
- return false, syscall.Errno(-1 * retCode)
- }
-
- return true, nil
-}
-
-// AddArch adds an architecture to the filter.
-// Accepts an architecture constant.
-// Returns an error on invalid filter context or architecture token, or an
-// issue with the call to libseccomp.
-func (f *ScmpFilter) AddArch(arch ScmpArch) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if err := sanitizeArch(arch); err != nil {
- return err
- } else if !f.valid {
- return errBadFilter
- }
-
- // Libseccomp returns -EEXIST if the specified architecture is already
- // present. Succeed silently in this case, as it's not fatal, and the
- // architecture is present already.
- retCode := C.seccomp_arch_add(f.filterCtx, arch.toNative())
- if retCode != 0 && syscall.Errno(-1*retCode) != syscall.EEXIST {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
-
-// RemoveArch removes an architecture from the filter.
-// Accepts an architecture constant.
-// Returns an error on invalid filter context or architecture token, or an
-// issue with the call to libseccomp.
-func (f *ScmpFilter) RemoveArch(arch ScmpArch) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if err := sanitizeArch(arch); err != nil {
- return err
- } else if !f.valid {
- return errBadFilter
- }
-
- // Similar to AddArch, -EEXIST is returned if the arch is not present
- // Succeed silently in that case, this is not fatal and the architecture
- // is not present in the filter after RemoveArch
- retCode := C.seccomp_arch_remove(f.filterCtx, arch.toNative())
- if retCode != 0 && syscall.Errno(-1*retCode) != syscall.EEXIST {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
-
-// Load loads a filter context into the kernel.
-// Returns an error if the filter context is invalid or the syscall failed.
-func (f *ScmpFilter) Load() error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if !f.valid {
- return errBadFilter
- }
-
- if retCode := C.seccomp_load(f.filterCtx); retCode != 0 {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
-
-// GetDefaultAction returns the default action taken on a syscall which does not
-// match a rule in the filter, or an error if an issue was encountered
-// retrieving the value.
-func (f *ScmpFilter) GetDefaultAction() (ScmpAction, error) {
- action, err := f.getFilterAttr(filterAttrActDefault)
- if err != nil {
- return 0x0, err
- }
-
- return actionFromNative(action)
-}
-
-// GetBadArchAction returns the default action taken on a syscall for an
-// architecture not in the filter, or an error if an issue was encountered
-// retrieving the value.
-func (f *ScmpFilter) GetBadArchAction() (ScmpAction, error) {
- action, err := f.getFilterAttr(filterAttrActBadArch)
- if err != nil {
- return 0x0, err
- }
-
- return actionFromNative(action)
-}
-
-// GetNoNewPrivsBit returns the current state the No New Privileges bit will be set
-// to on the filter being loaded, or an error if an issue was encountered
-// retrieving the value.
-// The No New Privileges bit tells the kernel that new processes run with exec()
-// cannot gain more privileges than the process that ran exec().
-// For example, a process with No New Privileges set would be unable to exec
-// setuid/setgid executables.
-func (f *ScmpFilter) GetNoNewPrivsBit() (bool, error) {
- noNewPrivs, err := f.getFilterAttr(filterAttrNNP)
- if err != nil {
- return false, err
- }
-
- if noNewPrivs == 0 {
- return false, nil
- }
-
- return true, nil
-}
-
-// GetTsyncBit returns whether Thread Synchronization will be enabled on the
-// filter being loaded, or an error if an issue was encountered retrieving the
-// value.
-// Thread Sync ensures that all members of the thread group of the calling
-// process will share the same Seccomp filter set.
-// Tsync is a fairly recent addition to the Linux kernel and older kernels
-// lack support. If the running kernel does not support Tsync and it is
-// requested in a filter, Libseccomp will not enable TSync support and will
-// proceed as normal.
-// This function is unavailable before v2.2 of libseccomp and will return an
-// error.
-func (f *ScmpFilter) GetTsyncBit() (bool, error) {
- tSync, err := f.getFilterAttr(filterAttrTsync)
- if err != nil {
- return false, err
- }
-
- if tSync == 0 {
- return false, nil
- }
-
- return true, nil
-}
-
-// SetBadArchAction sets the default action taken on a syscall for an
-// architecture not in the filter, or an error if an issue was encountered
-// setting the value.
-func (f *ScmpFilter) SetBadArchAction(action ScmpAction) error {
- if err := sanitizeAction(action); err != nil {
- return err
- }
-
- return f.setFilterAttr(filterAttrActBadArch, action.toNative())
-}
-
-// SetNoNewPrivsBit sets the state of the No New Privileges bit, which will be
-// applied on filter load, or an error if an issue was encountered setting the
-// value.
-// Filters with No New Privileges set to 0 can only be loaded if the process
-// has the CAP_SYS_ADMIN capability.
-func (f *ScmpFilter) SetNoNewPrivsBit(state bool) error {
- var toSet C.uint32_t = 0x0
-
- if state {
- toSet = 0x1
- }
-
- return f.setFilterAttr(filterAttrNNP, toSet)
-}
-
-// SetTsync sets whether Thread Synchronization will be enabled on the filter
-// being loaded. Returns an error if setting Tsync failed, or the filter is
-// invalid.
-// Thread Sync ensures that all members of the thread group of the calling
-// process will share the same Seccomp filter set.
-// Tsync is a fairly recent addition to the Linux kernel and older kernels
-// lack support. If the running kernel does not support Tsync and it is
-// requested in a filter, Libseccomp will not enable TSync support and will
-// proceed as normal.
-// This function is unavailable before v2.2 of libseccomp and will return an
-// error.
-func (f *ScmpFilter) SetTsync(enable bool) error {
- var toSet C.uint32_t = 0x0
-
- if enable {
- toSet = 0x1
- }
-
- return f.setFilterAttr(filterAttrTsync, toSet)
-}
-
-// SetSyscallPriority sets a syscall's priority.
-// This provides a hint to the filter generator in libseccomp about the
-// importance of this syscall. High-priority syscalls are placed
-// first in the filter code, and incur less overhead (at the expense of
-// lower-priority syscalls).
-func (f *ScmpFilter) SetSyscallPriority(call ScmpSyscall, priority uint8) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if !f.valid {
- return errBadFilter
- }
-
- if retCode := C.seccomp_syscall_priority(f.filterCtx, C.int(call),
- C.uint8_t(priority)); retCode != 0 {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
-
-// AddRule adds a single rule for an unconditional action on a syscall.
-// Accepts the number of the syscall and the action to be taken on the call
-// being made.
-// Returns an error if an issue was encountered adding the rule.
-func (f *ScmpFilter) AddRule(call ScmpSyscall, action ScmpAction) error {
- return f.addRuleGeneric(call, action, false, nil)
-}
-
-// AddRuleExact adds a single rule for an unconditional action on a syscall.
-// Accepts the number of the syscall and the action to be taken on the call
-// being made.
-// No modifications will be made to the rule, and it will fail to add if it
-// cannot be applied to the current architecture without modification.
-// The rule will function exactly as described, but it may not function identically
-// (or be able to be applied to) all architectures.
-// Returns an error if an issue was encountered adding the rule.
-func (f *ScmpFilter) AddRuleExact(call ScmpSyscall, action ScmpAction) error {
- return f.addRuleGeneric(call, action, true, nil)
-}
-
-// AddRuleConditional adds a single rule for a conditional action on a syscall.
-// Returns an error if an issue was encountered adding the rule.
-// All conditions must match for the rule to match.
-// There is a bug in library versions below v2.2.1 which can, in some cases,
-// cause conditions to be lost when more than one are used. Consequently,
-// AddRuleConditional is disabled on library versions lower than v2.2.1
-func (f *ScmpFilter) AddRuleConditional(call ScmpSyscall, action ScmpAction, conds []ScmpCondition) error {
- return f.addRuleGeneric(call, action, false, conds)
-}
-
-// AddRuleConditionalExact adds a single rule for a conditional action on a
-// syscall.
-// No modifications will be made to the rule, and it will fail to add if it
-// cannot be applied to the current architecture without modification.
-// The rule will function exactly as described, but it may not function identically
-// (or be able to be applied to) all architectures.
-// Returns an error if an issue was encountered adding the rule.
-// There is a bug in library versions below v2.2.1 which can, in some cases,
-// cause conditions to be lost when more than one are used. Consequently,
-// AddRuleConditionalExact is disabled on library versions lower than v2.2.1
-func (f *ScmpFilter) AddRuleConditionalExact(call ScmpSyscall, action ScmpAction, conds []ScmpCondition) error {
- return f.addRuleGeneric(call, action, true, conds)
-}
-
-// ExportPFC output PFC-formatted, human-readable dump of a filter context's
-// rules to a file.
-// Accepts file to write to (must be open for writing).
-// Returns an error if writing to the file fails.
-func (f *ScmpFilter) ExportPFC(file *os.File) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- fd := file.Fd()
-
- if !f.valid {
- return errBadFilter
- }
-
- if retCode := C.seccomp_export_pfc(f.filterCtx, C.int(fd)); retCode != 0 {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
-
-// ExportBPF outputs Berkeley Packet Filter-formatted, kernel-readable dump of a
-// filter context's rules to a file.
-// Accepts file to write to (must be open for writing).
-// Returns an error if writing to the file fails.
-func (f *ScmpFilter) ExportBPF(file *os.File) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- fd := file.Fd()
-
- if !f.valid {
- return errBadFilter
- }
-
- if retCode := C.seccomp_export_bpf(f.filterCtx, C.int(fd)); retCode != 0 {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/seccomp/libseccomp-golang/seccomp_internal.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/seccomp/libseccomp-golang/seccomp_internal.go
deleted file mode 100644
index 306ed175..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/seccomp/libseccomp-golang/seccomp_internal.go
+++ /dev/null
@@ -1,461 +0,0 @@
-// +build linux
-
-// Internal functions for libseccomp Go bindings
-// No exported functions
-
-package seccomp
-
-import (
- "fmt"
- "os"
- "syscall"
-)
-
-// Unexported C wrapping code - provides the C-Golang interface
-// Get the seccomp header in scope
-// Need stdlib.h for free() on cstrings
-
-// #cgo LDFLAGS: -lseccomp
-/*
-#include
-#include
-
-#if SCMP_VER_MAJOR < 2
-#error Minimum supported version of Libseccomp is v2.1.0
-#elif SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 1
-#error Minimum supported version of Libseccomp is v2.1.0
-#endif
-
-#define ARCH_BAD ~0
-
-const uint32_t C_ARCH_BAD = ARCH_BAD;
-
-#ifndef SCMP_ARCH_AARCH64
-#define SCMP_ARCH_AARCH64 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPS
-#define SCMP_ARCH_MIPS ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPS64
-#define SCMP_ARCH_MIPS64 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPS64N32
-#define SCMP_ARCH_MIPS64N32 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPSEL
-#define SCMP_ARCH_MIPSEL ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPSEL64
-#define SCMP_ARCH_MIPSEL64 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPSEL64N32
-#define SCMP_ARCH_MIPSEL64N32 ARCH_BAD
-#endif
-
-const uint32_t C_ARCH_NATIVE = SCMP_ARCH_NATIVE;
-const uint32_t C_ARCH_X86 = SCMP_ARCH_X86;
-const uint32_t C_ARCH_X86_64 = SCMP_ARCH_X86_64;
-const uint32_t C_ARCH_X32 = SCMP_ARCH_X32;
-const uint32_t C_ARCH_ARM = SCMP_ARCH_ARM;
-const uint32_t C_ARCH_AARCH64 = SCMP_ARCH_AARCH64;
-const uint32_t C_ARCH_MIPS = SCMP_ARCH_MIPS;
-const uint32_t C_ARCH_MIPS64 = SCMP_ARCH_MIPS64;
-const uint32_t C_ARCH_MIPS64N32 = SCMP_ARCH_MIPS64N32;
-const uint32_t C_ARCH_MIPSEL = SCMP_ARCH_MIPSEL;
-const uint32_t C_ARCH_MIPSEL64 = SCMP_ARCH_MIPSEL64;
-const uint32_t C_ARCH_MIPSEL64N32 = SCMP_ARCH_MIPSEL64N32;
-
-const uint32_t C_ACT_KILL = SCMP_ACT_KILL;
-const uint32_t C_ACT_TRAP = SCMP_ACT_TRAP;
-const uint32_t C_ACT_ERRNO = SCMP_ACT_ERRNO(0);
-const uint32_t C_ACT_TRACE = SCMP_ACT_TRACE(0);
-const uint32_t C_ACT_ALLOW = SCMP_ACT_ALLOW;
-
-// If TSync is not supported, make sure it doesn't map to a supported filter attribute
-// Don't worry about major version < 2, the minimum version checks should catch that case
-#if SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 2
-#define SCMP_FLTATR_CTL_TSYNC _SCMP_CMP_MIN
-#endif
-
-const uint32_t C_ATTRIBUTE_DEFAULT = (uint32_t)SCMP_FLTATR_ACT_DEFAULT;
-const uint32_t C_ATTRIBUTE_BADARCH = (uint32_t)SCMP_FLTATR_ACT_BADARCH;
-const uint32_t C_ATTRIBUTE_NNP = (uint32_t)SCMP_FLTATR_CTL_NNP;
-const uint32_t C_ATTRIBUTE_TSYNC = (uint32_t)SCMP_FLTATR_CTL_TSYNC;
-
-const int C_CMP_NE = (int)SCMP_CMP_NE;
-const int C_CMP_LT = (int)SCMP_CMP_LT;
-const int C_CMP_LE = (int)SCMP_CMP_LE;
-const int C_CMP_EQ = (int)SCMP_CMP_EQ;
-const int C_CMP_GE = (int)SCMP_CMP_GE;
-const int C_CMP_GT = (int)SCMP_CMP_GT;
-const int C_CMP_MASKED_EQ = (int)SCMP_CMP_MASKED_EQ;
-
-const int C_VERSION_MAJOR = SCMP_VER_MAJOR;
-const int C_VERSION_MINOR = SCMP_VER_MINOR;
-const int C_VERSION_MICRO = SCMP_VER_MICRO;
-
-typedef struct scmp_arg_cmp* scmp_cast_t;
-
-// Wrapper to create an scmp_arg_cmp struct
-void*
-make_struct_arg_cmp(
- unsigned int arg,
- int compare,
- uint64_t a,
- uint64_t b
- )
-{
- struct scmp_arg_cmp *s = malloc(sizeof(struct scmp_arg_cmp));
-
- s->arg = arg;
- s->op = compare;
- s->datum_a = a;
- s->datum_b = b;
-
- return s;
-}
-*/
-import "C"
-
-// Nonexported types
-type scmpFilterAttr uint32
-
-// Nonexported constants
-
-const (
- filterAttrActDefault scmpFilterAttr = iota
- filterAttrActBadArch scmpFilterAttr = iota
- filterAttrNNP scmpFilterAttr = iota
- filterAttrTsync scmpFilterAttr = iota
-)
-
-const (
- // An error return from certain libseccomp functions
- scmpError C.int = -1
- // Comparison boundaries to check for architecture validity
- archStart ScmpArch = ArchNative
- archEnd ScmpArch = ArchMIPSEL64N32
- // Comparison boundaries to check for action validity
- actionStart ScmpAction = ActKill
- actionEnd ScmpAction = ActAllow
- // Comparison boundaries to check for comparison operator validity
- compareOpStart ScmpCompareOp = CompareNotEqual
- compareOpEnd ScmpCompareOp = CompareMaskedEqual
-)
-
-var (
- // Error thrown on bad filter context
- errBadFilter = fmt.Errorf("filter is invalid or uninitialized")
- // Constants representing library major, minor, and micro versions
- verMajor = int(C.C_VERSION_MAJOR)
- verMinor = int(C.C_VERSION_MINOR)
- verMicro = int(C.C_VERSION_MICRO)
-)
-
-// Nonexported functions
-
-// Check if library version is greater than or equal to the given one
-func checkVersionAbove(major, minor, micro int) bool {
- return (verMajor > major) ||
- (verMajor == major && verMinor > minor) ||
- (verMajor == major && verMinor == minor && verMicro >= micro)
-}
-
-// Init function: Verify library version is appropriate
-func init() {
- if !checkVersionAbove(2, 1, 0) {
- fmt.Fprintf(os.Stderr, "Libseccomp version too low: minimum supported is 2.1.0, detected %d.%d.%d", C.C_VERSION_MAJOR, C.C_VERSION_MINOR, C.C_VERSION_MICRO)
- os.Exit(-1)
- }
-}
-
-// Filter helpers
-
-// Filter finalizer - ensure that kernel context for filters is freed
-func filterFinalizer(f *ScmpFilter) {
- f.Release()
-}
-
-// Get a raw filter attribute
-func (f *ScmpFilter) getFilterAttr(attr scmpFilterAttr) (C.uint32_t, error) {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if !f.valid {
- return 0x0, errBadFilter
- }
-
- if !checkVersionAbove(2, 2, 0) && attr == filterAttrTsync {
- return 0x0, fmt.Errorf("the thread synchronization attribute is not supported in this version of the library")
- }
-
- var attribute C.uint32_t
-
- retCode := C.seccomp_attr_get(f.filterCtx, attr.toNative(), &attribute)
- if retCode != 0 {
- return 0x0, syscall.Errno(-1 * retCode)
- }
-
- return attribute, nil
-}
-
-// Set a raw filter attribute
-func (f *ScmpFilter) setFilterAttr(attr scmpFilterAttr, value C.uint32_t) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if !f.valid {
- return errBadFilter
- }
-
- if !checkVersionAbove(2, 2, 0) && attr == filterAttrTsync {
- return fmt.Errorf("the thread synchronization attribute is not supported in this version of the library")
- }
-
- retCode := C.seccomp_attr_set(f.filterCtx, attr.toNative(), value)
- if retCode != 0 {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
-
-// DOES NOT LOCK OR CHECK VALIDITY
-// Assumes caller has already done this
-// Wrapper for seccomp_rule_add_... functions
-func (f *ScmpFilter) addRuleWrapper(call ScmpSyscall, action ScmpAction, exact bool, cond C.scmp_cast_t) error {
- var length C.uint
- if cond != nil {
- length = 1
- } else {
- length = 0
- }
-
- var retCode C.int
- if exact {
- retCode = C.seccomp_rule_add_exact_array(f.filterCtx, action.toNative(), C.int(call), length, cond)
- } else {
- retCode = C.seccomp_rule_add_array(f.filterCtx, action.toNative(), C.int(call), length, cond)
- }
-
- if syscall.Errno(-1*retCode) == syscall.EFAULT {
- return fmt.Errorf("unrecognized syscall")
- } else if syscall.Errno(-1*retCode) == syscall.EPERM {
- return fmt.Errorf("requested action matches default action of filter")
- } else if retCode != 0 {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
-
-// Generic add function for filter rules
-func (f *ScmpFilter) addRuleGeneric(call ScmpSyscall, action ScmpAction, exact bool, conds []ScmpCondition) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if !f.valid {
- return errBadFilter
- }
-
- if len(conds) == 0 {
- if err := f.addRuleWrapper(call, action, exact, nil); err != nil {
- return err
- }
- } else {
- // We don't support conditional filtering in library version v2.1
- if !checkVersionAbove(2, 2, 1) {
- return fmt.Errorf("conditional filtering requires libseccomp version >= 2.2.1")
- }
-
- for _, cond := range conds {
- cmpStruct := C.make_struct_arg_cmp(C.uint(cond.Argument), cond.Op.toNative(), C.uint64_t(cond.Operand1), C.uint64_t(cond.Operand2))
- defer C.free(cmpStruct)
-
- if err := f.addRuleWrapper(call, action, exact, C.scmp_cast_t(cmpStruct)); err != nil {
- return err
- }
- }
- }
-
- return nil
-}
-
-// Generic Helpers
-
-// Helper - Sanitize Arch token input
-func sanitizeArch(in ScmpArch) error {
- if in < archStart || in > archEnd {
- return fmt.Errorf("unrecognized architecture")
- }
-
- if in.toNative() == C.C_ARCH_BAD {
- return fmt.Errorf("architecture is not supported on this version of the library")
- }
-
- return nil
-}
-
-func sanitizeAction(in ScmpAction) error {
- inTmp := in & 0x0000FFFF
- if inTmp < actionStart || inTmp > actionEnd {
- return fmt.Errorf("unrecognized action")
- }
-
- if inTmp != ActTrace && inTmp != ActErrno && (in&0xFFFF0000) != 0 {
- return fmt.Errorf("highest 16 bits must be zeroed except for Trace and Errno")
- }
-
- return nil
-}
-
-func sanitizeCompareOp(in ScmpCompareOp) error {
- if in < compareOpStart || in > compareOpEnd {
- return fmt.Errorf("unrecognized comparison operator")
- }
-
- return nil
-}
-
-func archFromNative(a C.uint32_t) (ScmpArch, error) {
- switch a {
- case C.C_ARCH_X86:
- return ArchX86, nil
- case C.C_ARCH_X86_64:
- return ArchAMD64, nil
- case C.C_ARCH_X32:
- return ArchX32, nil
- case C.C_ARCH_ARM:
- return ArchARM, nil
- case C.C_ARCH_NATIVE:
- return ArchNative, nil
- case C.C_ARCH_AARCH64:
- return ArchARM64, nil
- case C.C_ARCH_MIPS:
- return ArchMIPS, nil
- case C.C_ARCH_MIPS64:
- return ArchMIPS64, nil
- case C.C_ARCH_MIPS64N32:
- return ArchMIPS64N32, nil
- case C.C_ARCH_MIPSEL:
- return ArchMIPSEL, nil
- case C.C_ARCH_MIPSEL64:
- return ArchMIPSEL64, nil
- case C.C_ARCH_MIPSEL64N32:
- return ArchMIPSEL64N32, nil
- default:
- return 0x0, fmt.Errorf("unrecognized architecture")
- }
-}
-
-// Only use with sanitized arches, no error handling
-func (a ScmpArch) toNative() C.uint32_t {
- switch a {
- case ArchX86:
- return C.C_ARCH_X86
- case ArchAMD64:
- return C.C_ARCH_X86_64
- case ArchX32:
- return C.C_ARCH_X32
- case ArchARM:
- return C.C_ARCH_ARM
- case ArchARM64:
- return C.C_ARCH_AARCH64
- case ArchMIPS:
- return C.C_ARCH_MIPS
- case ArchMIPS64:
- return C.C_ARCH_MIPS64
- case ArchMIPS64N32:
- return C.C_ARCH_MIPS64N32
- case ArchMIPSEL:
- return C.C_ARCH_MIPSEL
- case ArchMIPSEL64:
- return C.C_ARCH_MIPSEL64
- case ArchMIPSEL64N32:
- return C.C_ARCH_MIPSEL64N32
- case ArchNative:
- return C.C_ARCH_NATIVE
- default:
- return 0x0
- }
-}
-
-// Only use with sanitized ops, no error handling
-func (a ScmpCompareOp) toNative() C.int {
- switch a {
- case CompareNotEqual:
- return C.C_CMP_NE
- case CompareLess:
- return C.C_CMP_LT
- case CompareLessOrEqual:
- return C.C_CMP_LE
- case CompareEqual:
- return C.C_CMP_EQ
- case CompareGreaterEqual:
- return C.C_CMP_GE
- case CompareGreater:
- return C.C_CMP_GT
- case CompareMaskedEqual:
- return C.C_CMP_MASKED_EQ
- default:
- return 0x0
- }
-}
-
-func actionFromNative(a C.uint32_t) (ScmpAction, error) {
- aTmp := a & 0xFFFF
- switch a & 0xFFFF0000 {
- case C.C_ACT_KILL:
- return ActKill, nil
- case C.C_ACT_TRAP:
- return ActTrap, nil
- case C.C_ACT_ERRNO:
- return ActErrno.SetReturnCode(int16(aTmp)), nil
- case C.C_ACT_TRACE:
- return ActTrace.SetReturnCode(int16(aTmp)), nil
- case C.C_ACT_ALLOW:
- return ActAllow, nil
- default:
- return 0x0, fmt.Errorf("unrecognized action")
- }
-}
-
-// Only use with sanitized actions, no error handling
-func (a ScmpAction) toNative() C.uint32_t {
- switch a & 0xFFFF {
- case ActKill:
- return C.C_ACT_KILL
- case ActTrap:
- return C.C_ACT_TRAP
- case ActErrno:
- return C.C_ACT_ERRNO | (C.uint32_t(a) >> 16)
- case ActTrace:
- return C.C_ACT_TRACE | (C.uint32_t(a) >> 16)
- case ActAllow:
- return C.C_ACT_ALLOW
- default:
- return 0x0
- }
-}
-
-// Internal only, assumes safe attribute
-func (a scmpFilterAttr) toNative() uint32 {
- switch a {
- case filterAttrActDefault:
- return uint32(C.C_ATTRIBUTE_DEFAULT)
- case filterAttrActBadArch:
- return uint32(C.C_ATTRIBUTE_BADARCH)
- case filterAttrNNP:
- return uint32(C.C_ATTRIBUTE_NNP)
- case filterAttrTsync:
- return uint32(C.C_ATTRIBUTE_TSYNC)
- default:
- return 0x0
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/LICENSE b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/LICENSE
deleted file mode 100644
index 80dd96de..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/LICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-Copyright 2013 Suryandaru Triandana
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/capability.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/capability.go
deleted file mode 100644
index c13f4e52..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/capability.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2013, Suryandaru Triandana
-// All rights reserved.
-//
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Package capability provides utilities for manipulating POSIX capabilities.
-package capability
-
-type Capabilities interface {
- // Get check whether a capability present in the given
- // capabilities set. The 'which' value should be one of EFFECTIVE,
- // PERMITTED, INHERITABLE or BOUNDING.
- Get(which CapType, what Cap) bool
-
- // Empty check whether all capability bits of the given capabilities
- // set are zero. The 'which' value should be one of EFFECTIVE,
- // PERMITTED, INHERITABLE or BOUNDING.
- Empty(which CapType) bool
-
- // Full check whether all capability bits of the given capabilities
- // set are one. The 'which' value should be one of EFFECTIVE,
- // PERMITTED, INHERITABLE or BOUNDING.
- Full(which CapType) bool
-
- // Set sets capabilities of the given capabilities sets. The
- // 'which' value should be one or combination (OR'ed) of EFFECTIVE,
- // PERMITTED, INHERITABLE or BOUNDING.
- Set(which CapType, caps ...Cap)
-
- // Unset unsets capabilities of the given capabilities sets. The
- // 'which' value should be one or combination (OR'ed) of EFFECTIVE,
- // PERMITTED, INHERITABLE or BOUNDING.
- Unset(which CapType, caps ...Cap)
-
- // Fill sets all bits of the given capabilities kind to one. The
- // 'kind' value should be one or combination (OR'ed) of CAPS or
- // BOUNDS.
- Fill(kind CapType)
-
- // Clear sets all bits of the given capabilities kind to zero. The
- // 'kind' value should be one or combination (OR'ed) of CAPS or
- // BOUNDS.
- Clear(kind CapType)
-
- // String return current capabilities state of the given capabilities
- // set as string. The 'which' value should be one of EFFECTIVE,
- // PERMITTED, INHERITABLE or BOUNDING.
- StringCap(which CapType) string
-
- // String return current capabilities state as string.
- String() string
-
- // Load load actual capabilities value. This will overwrite all
- // outstanding changes.
- Load() error
-
- // Apply apply the capabilities settings, so all changes will take
- // effect.
- Apply(kind CapType) error
-}
-
-// NewPid create new initialized Capabilities object for given pid when it
-// is nonzero, or for the current pid if pid is 0
-func NewPid(pid int) (Capabilities, error) {
- return newPid(pid)
-}
-
-// NewFile create new initialized Capabilities object for given named file.
-func NewFile(name string) (Capabilities, error) {
- return newFile(name)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/capability_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/capability_linux.go
deleted file mode 100644
index 3dfcd398..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/capability_linux.go
+++ /dev/null
@@ -1,608 +0,0 @@
-// Copyright (c) 2013, Suryandaru Triandana
-// All rights reserved.
-//
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package capability
-
-import (
- "bufio"
- "errors"
- "fmt"
- "io"
- "os"
- "strings"
- "syscall"
-)
-
-var errUnknownVers = errors.New("unknown capability version")
-
-const (
- linuxCapVer1 = 0x19980330
- linuxCapVer2 = 0x20071026
- linuxCapVer3 = 0x20080522
-)
-
-var (
- capVers uint32
- capLastCap Cap
-)
-
-func init() {
- var hdr capHeader
- capget(&hdr, nil)
- capVers = hdr.version
-
- if initLastCap() == nil {
- CAP_LAST_CAP = capLastCap
- if capLastCap > 31 {
- capUpperMask = (uint32(1) << (uint(capLastCap) - 31)) - 1
- } else {
- capUpperMask = 0
- }
- }
-}
-
-func initLastCap() error {
- if capLastCap != 0 {
- return nil
- }
-
- f, err := os.Open("/proc/sys/kernel/cap_last_cap")
- if err != nil {
- return err
- }
- defer f.Close()
-
- var b []byte = make([]byte, 11)
- _, err = f.Read(b)
- if err != nil {
- return err
- }
-
- fmt.Sscanf(string(b), "%d", &capLastCap)
-
- return nil
-}
-
-func mkStringCap(c Capabilities, which CapType) (ret string) {
- for i, first := Cap(0), true; i <= CAP_LAST_CAP; i++ {
- if !c.Get(which, i) {
- continue
- }
- if first {
- first = false
- } else {
- ret += ", "
- }
- ret += i.String()
- }
- return
-}
-
-func mkString(c Capabilities, max CapType) (ret string) {
- ret = "{"
- for i := CapType(1); i <= max; i <<= 1 {
- ret += " " + i.String() + "=\""
- if c.Empty(i) {
- ret += "empty"
- } else if c.Full(i) {
- ret += "full"
- } else {
- ret += c.StringCap(i)
- }
- ret += "\""
- }
- ret += " }"
- return
-}
-
-func newPid(pid int) (c Capabilities, err error) {
- switch capVers {
- case linuxCapVer1:
- p := new(capsV1)
- p.hdr.version = capVers
- p.hdr.pid = pid
- c = p
- case linuxCapVer2, linuxCapVer3:
- p := new(capsV3)
- p.hdr.version = capVers
- p.hdr.pid = pid
- c = p
- default:
- err = errUnknownVers
- return
- }
- err = c.Load()
- if err != nil {
- c = nil
- }
- return
-}
-
-type capsV1 struct {
- hdr capHeader
- data capData
-}
-
-func (c *capsV1) Get(which CapType, what Cap) bool {
- if what > 32 {
- return false
- }
-
- switch which {
- case EFFECTIVE:
- return (1< 32 {
- continue
- }
-
- if which&EFFECTIVE != 0 {
- c.data.effective |= 1 << uint(what)
- }
- if which&PERMITTED != 0 {
- c.data.permitted |= 1 << uint(what)
- }
- if which&INHERITABLE != 0 {
- c.data.inheritable |= 1 << uint(what)
- }
- }
-}
-
-func (c *capsV1) Unset(which CapType, caps ...Cap) {
- for _, what := range caps {
- if what > 32 {
- continue
- }
-
- if which&EFFECTIVE != 0 {
- c.data.effective &= ^(1 << uint(what))
- }
- if which&PERMITTED != 0 {
- c.data.permitted &= ^(1 << uint(what))
- }
- if which&INHERITABLE != 0 {
- c.data.inheritable &= ^(1 << uint(what))
- }
- }
-}
-
-func (c *capsV1) Fill(kind CapType) {
- if kind&CAPS == CAPS {
- c.data.effective = 0x7fffffff
- c.data.permitted = 0x7fffffff
- c.data.inheritable = 0
- }
-}
-
-func (c *capsV1) Clear(kind CapType) {
- if kind&CAPS == CAPS {
- c.data.effective = 0
- c.data.permitted = 0
- c.data.inheritable = 0
- }
-}
-
-func (c *capsV1) StringCap(which CapType) (ret string) {
- return mkStringCap(c, which)
-}
-
-func (c *capsV1) String() (ret string) {
- return mkString(c, BOUNDING)
-}
-
-func (c *capsV1) Load() (err error) {
- return capget(&c.hdr, &c.data)
-}
-
-func (c *capsV1) Apply(kind CapType) error {
- if kind&CAPS == CAPS {
- return capset(&c.hdr, &c.data)
- }
- return nil
-}
-
-type capsV3 struct {
- hdr capHeader
- data [2]capData
- bounds [2]uint32
-}
-
-func (c *capsV3) Get(which CapType, what Cap) bool {
- var i uint
- if what > 31 {
- i = uint(what) >> 5
- what %= 32
- }
-
- switch which {
- case EFFECTIVE:
- return (1< 31 {
- i = uint(what) >> 5
- what %= 32
- }
-
- if which&EFFECTIVE != 0 {
- c.data[i].effective |= 1 << uint(what)
- }
- if which&PERMITTED != 0 {
- c.data[i].permitted |= 1 << uint(what)
- }
- if which&INHERITABLE != 0 {
- c.data[i].inheritable |= 1 << uint(what)
- }
- if which&BOUNDING != 0 {
- c.bounds[i] |= 1 << uint(what)
- }
- }
-}
-
-func (c *capsV3) Unset(which CapType, caps ...Cap) {
- for _, what := range caps {
- var i uint
- if what > 31 {
- i = uint(what) >> 5
- what %= 32
- }
-
- if which&EFFECTIVE != 0 {
- c.data[i].effective &= ^(1 << uint(what))
- }
- if which&PERMITTED != 0 {
- c.data[i].permitted &= ^(1 << uint(what))
- }
- if which&INHERITABLE != 0 {
- c.data[i].inheritable &= ^(1 << uint(what))
- }
- if which&BOUNDING != 0 {
- c.bounds[i] &= ^(1 << uint(what))
- }
- }
-}
-
-func (c *capsV3) Fill(kind CapType) {
- if kind&CAPS == CAPS {
- c.data[0].effective = 0xffffffff
- c.data[0].permitted = 0xffffffff
- c.data[0].inheritable = 0
- c.data[1].effective = 0xffffffff
- c.data[1].permitted = 0xffffffff
- c.data[1].inheritable = 0
- }
-
- if kind&BOUNDS == BOUNDS {
- c.bounds[0] = 0xffffffff
- c.bounds[1] = 0xffffffff
- }
-}
-
-func (c *capsV3) Clear(kind CapType) {
- if kind&CAPS == CAPS {
- c.data[0].effective = 0
- c.data[0].permitted = 0
- c.data[0].inheritable = 0
- c.data[1].effective = 0
- c.data[1].permitted = 0
- c.data[1].inheritable = 0
- }
-
- if kind&BOUNDS == BOUNDS {
- c.bounds[0] = 0
- c.bounds[1] = 0
- }
-}
-
-func (c *capsV3) StringCap(which CapType) (ret string) {
- return mkStringCap(c, which)
-}
-
-func (c *capsV3) String() (ret string) {
- return mkString(c, BOUNDING)
-}
-
-func (c *capsV3) Load() (err error) {
- err = capget(&c.hdr, &c.data[0])
- if err != nil {
- return
- }
-
- var status_path string
-
- if c.hdr.pid == 0 {
- status_path = fmt.Sprintf("/proc/self/status")
- } else {
- status_path = fmt.Sprintf("/proc/%d/status", c.hdr.pid)
- }
-
- f, err := os.Open(status_path)
- if err != nil {
- return
- }
- b := bufio.NewReader(f)
- for {
- line, e := b.ReadString('\n')
- if e != nil {
- if e != io.EOF {
- err = e
- }
- break
- }
- if strings.HasPrefix(line, "CapB") {
- fmt.Sscanf(line[4:], "nd: %08x%08x", &c.bounds[1], &c.bounds[0])
- break
- }
- }
- f.Close()
-
- return
-}
-
-func (c *capsV3) Apply(kind CapType) (err error) {
- if kind&BOUNDS == BOUNDS {
- var data [2]capData
- err = capget(&c.hdr, &data[0])
- if err != nil {
- return
- }
- if (1< 31 {
- if c.data.version == 1 {
- return false
- }
- i = uint(what) >> 5
- what %= 32
- }
-
- switch which {
- case EFFECTIVE:
- return (1< 31 {
- if c.data.version == 1 {
- continue
- }
- i = uint(what) >> 5
- what %= 32
- }
-
- if which&EFFECTIVE != 0 {
- c.data.effective[i] |= 1 << uint(what)
- }
- if which&PERMITTED != 0 {
- c.data.data[i].permitted |= 1 << uint(what)
- }
- if which&INHERITABLE != 0 {
- c.data.data[i].inheritable |= 1 << uint(what)
- }
- }
-}
-
-func (c *capsFile) Unset(which CapType, caps ...Cap) {
- for _, what := range caps {
- var i uint
- if what > 31 {
- if c.data.version == 1 {
- continue
- }
- i = uint(what) >> 5
- what %= 32
- }
-
- if which&EFFECTIVE != 0 {
- c.data.effective[i] &= ^(1 << uint(what))
- }
- if which&PERMITTED != 0 {
- c.data.data[i].permitted &= ^(1 << uint(what))
- }
- if which&INHERITABLE != 0 {
- c.data.data[i].inheritable &= ^(1 << uint(what))
- }
- }
-}
-
-func (c *capsFile) Fill(kind CapType) {
- if kind&CAPS == CAPS {
- c.data.effective[0] = 0xffffffff
- c.data.data[0].permitted = 0xffffffff
- c.data.data[0].inheritable = 0
- if c.data.version == 2 {
- c.data.effective[1] = 0xffffffff
- c.data.data[1].permitted = 0xffffffff
- c.data.data[1].inheritable = 0
- }
- }
-}
-
-func (c *capsFile) Clear(kind CapType) {
- if kind&CAPS == CAPS {
- c.data.effective[0] = 0
- c.data.data[0].permitted = 0
- c.data.data[0].inheritable = 0
- if c.data.version == 2 {
- c.data.effective[1] = 0
- c.data.data[1].permitted = 0
- c.data.data[1].inheritable = 0
- }
- }
-}
-
-func (c *capsFile) StringCap(which CapType) (ret string) {
- return mkStringCap(c, which)
-}
-
-func (c *capsFile) String() (ret string) {
- return mkString(c, INHERITABLE)
-}
-
-func (c *capsFile) Load() (err error) {
- return getVfsCap(c.path, &c.data)
-}
-
-func (c *capsFile) Apply(kind CapType) (err error) {
- if kind&CAPS == CAPS {
- return setVfsCap(c.path, &c.data)
- }
- return
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/capability_noop.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/capability_noop.go
deleted file mode 100644
index 9bb3070c..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/capability_noop.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2013, Suryandaru Triandana
-// All rights reserved.
-//
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// +build !linux
-
-package capability
-
-import "errors"
-
-func newPid(pid int) (Capabilities, error) {
- return nil, errors.New("not supported")
-}
-
-func newFile(path string) (Capabilities, error) {
- return nil, errors.New("not supported")
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/enum.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/enum.go
deleted file mode 100644
index fd0ce7fe..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/enum.go
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright (c) 2013, Suryandaru Triandana
-// All rights reserved.
-//
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package capability
-
-type CapType uint
-
-func (c CapType) String() string {
- switch c {
- case EFFECTIVE:
- return "effective"
- case PERMITTED:
- return "permitted"
- case INHERITABLE:
- return "inheritable"
- case BOUNDING:
- return "bounding"
- case CAPS:
- return "caps"
- }
- return "unknown"
-}
-
-const (
- EFFECTIVE CapType = 1 << iota
- PERMITTED
- INHERITABLE
- BOUNDING
-
- CAPS = EFFECTIVE | PERMITTED | INHERITABLE
- BOUNDS = BOUNDING
-)
-
-//go:generate go run enumgen/gen.go
-type Cap int
-
-// POSIX-draft defined capabilities.
-const (
- // In a system with the [_POSIX_CHOWN_RESTRICTED] option defined, this
- // overrides the restriction of changing file ownership and group
- // ownership.
- CAP_CHOWN = Cap(0)
-
- // Override all DAC access, including ACL execute access if
- // [_POSIX_ACL] is defined. Excluding DAC access covered by
- // CAP_LINUX_IMMUTABLE.
- CAP_DAC_OVERRIDE = Cap(1)
-
- // Overrides all DAC restrictions regarding read and search on files
- // and directories, including ACL restrictions if [_POSIX_ACL] is
- // defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE.
- CAP_DAC_READ_SEARCH = Cap(2)
-
- // Overrides all restrictions about allowed operations on files, where
- // file owner ID must be equal to the user ID, except where CAP_FSETID
- // is applicable. It doesn't override MAC and DAC restrictions.
- CAP_FOWNER = Cap(3)
-
- // Overrides the following restrictions that the effective user ID
- // shall match the file owner ID when setting the S_ISUID and S_ISGID
- // bits on that file; that the effective group ID (or one of the
- // supplementary group IDs) shall match the file owner ID when setting
- // the S_ISGID bit on that file; that the S_ISUID and S_ISGID bits are
- // cleared on successful return from chown(2) (not implemented).
- CAP_FSETID = Cap(4)
-
- // Overrides the restriction that the real or effective user ID of a
- // process sending a signal must match the real or effective user ID
- // of the process receiving the signal.
- CAP_KILL = Cap(5)
-
- // Allows setgid(2) manipulation
- // Allows setgroups(2)
- // Allows forged gids on socket credentials passing.
- CAP_SETGID = Cap(6)
-
- // Allows set*uid(2) manipulation (including fsuid).
- // Allows forged pids on socket credentials passing.
- CAP_SETUID = Cap(7)
-
- // Linux-specific capabilities
-
- // Without VFS support for capabilities:
- // Transfer any capability in your permitted set to any pid,
- // remove any capability in your permitted set from any pid
- // With VFS support for capabilities (neither of above, but)
- // Add any capability from current's capability bounding set
- // to the current process' inheritable set
- // Allow taking bits out of capability bounding set
- // Allow modification of the securebits for a process
- CAP_SETPCAP = Cap(8)
-
- // Allow modification of S_IMMUTABLE and S_APPEND file attributes
- CAP_LINUX_IMMUTABLE = Cap(9)
-
- // Allows binding to TCP/UDP sockets below 1024
- // Allows binding to ATM VCIs below 32
- CAP_NET_BIND_SERVICE = Cap(10)
-
- // Allow broadcasting, listen to multicast
- CAP_NET_BROADCAST = Cap(11)
-
- // Allow interface configuration
- // Allow administration of IP firewall, masquerading and accounting
- // Allow setting debug option on sockets
- // Allow modification of routing tables
- // Allow setting arbitrary process / process group ownership on
- // sockets
- // Allow binding to any address for transparent proxying (also via NET_RAW)
- // Allow setting TOS (type of service)
- // Allow setting promiscuous mode
- // Allow clearing driver statistics
- // Allow multicasting
- // Allow read/write of device-specific registers
- // Allow activation of ATM control sockets
- CAP_NET_ADMIN = Cap(12)
-
- // Allow use of RAW sockets
- // Allow use of PACKET sockets
- // Allow binding to any address for transparent proxying (also via NET_ADMIN)
- CAP_NET_RAW = Cap(13)
-
- // Allow locking of shared memory segments
- // Allow mlock and mlockall (which doesn't really have anything to do
- // with IPC)
- CAP_IPC_LOCK = Cap(14)
-
- // Override IPC ownership checks
- CAP_IPC_OWNER = Cap(15)
-
- // Insert and remove kernel modules - modify kernel without limit
- CAP_SYS_MODULE = Cap(16)
-
- // Allow ioperm/iopl access
- // Allow sending USB messages to any device via /proc/bus/usb
- CAP_SYS_RAWIO = Cap(17)
-
- // Allow use of chroot()
- CAP_SYS_CHROOT = Cap(18)
-
- // Allow ptrace() of any process
- CAP_SYS_PTRACE = Cap(19)
-
- // Allow configuration of process accounting
- CAP_SYS_PACCT = Cap(20)
-
- // Allow configuration of the secure attention key
- // Allow administration of the random device
- // Allow examination and configuration of disk quotas
- // Allow setting the domainname
- // Allow setting the hostname
- // Allow calling bdflush()
- // Allow mount() and umount(), setting up new smb connection
- // Allow some autofs root ioctls
- // Allow nfsservctl
- // Allow VM86_REQUEST_IRQ
- // Allow to read/write pci config on alpha
- // Allow irix_prctl on mips (setstacksize)
- // Allow flushing all cache on m68k (sys_cacheflush)
- // Allow removing semaphores
- // Used instead of CAP_CHOWN to "chown" IPC message queues, semaphores
- // and shared memory
- // Allow locking/unlocking of shared memory segment
- // Allow turning swap on/off
- // Allow forged pids on socket credentials passing
- // Allow setting readahead and flushing buffers on block devices
- // Allow setting geometry in floppy driver
- // Allow turning DMA on/off in xd driver
- // Allow administration of md devices (mostly the above, but some
- // extra ioctls)
- // Allow tuning the ide driver
- // Allow access to the nvram device
- // Allow administration of apm_bios, serial and bttv (TV) device
- // Allow manufacturer commands in isdn CAPI support driver
- // Allow reading non-standardized portions of pci configuration space
- // Allow DDI debug ioctl on sbpcd driver
- // Allow setting up serial ports
- // Allow sending raw qic-117 commands
- // Allow enabling/disabling tagged queuing on SCSI controllers and sending
- // arbitrary SCSI commands
- // Allow setting encryption key on loopback filesystem
- // Allow setting zone reclaim policy
- CAP_SYS_ADMIN = Cap(21)
-
- // Allow use of reboot()
- CAP_SYS_BOOT = Cap(22)
-
- // Allow raising priority and setting priority on other (different
- // UID) processes
- // Allow use of FIFO and round-robin (realtime) scheduling on own
- // processes and setting the scheduling algorithm used by another
- // process.
- // Allow setting cpu affinity on other processes
- CAP_SYS_NICE = Cap(23)
-
- // Override resource limits. Set resource limits.
- // Override quota limits.
- // Override reserved space on ext2 filesystem
- // Modify data journaling mode on ext3 filesystem (uses journaling
- // resources)
- // NOTE: ext2 honors fsuid when checking for resource overrides, so
- // you can override using fsuid too
- // Override size restrictions on IPC message queues
- // Allow more than 64hz interrupts from the real-time clock
- // Override max number of consoles on console allocation
- // Override max number of keymaps
- CAP_SYS_RESOURCE = Cap(24)
-
- // Allow manipulation of system clock
- // Allow irix_stime on mips
- // Allow setting the real-time clock
- CAP_SYS_TIME = Cap(25)
-
- // Allow configuration of tty devices
- // Allow vhangup() of tty
- CAP_SYS_TTY_CONFIG = Cap(26)
-
- // Allow the privileged aspects of mknod()
- CAP_MKNOD = Cap(27)
-
- // Allow taking of leases on files
- CAP_LEASE = Cap(28)
-
- CAP_AUDIT_WRITE = Cap(29)
- CAP_AUDIT_CONTROL = Cap(30)
- CAP_SETFCAP = Cap(31)
-
- // Override MAC access.
- // The base kernel enforces no MAC policy.
- // An LSM may enforce a MAC policy, and if it does and it chooses
- // to implement capability based overrides of that policy, this is
- // the capability it should use to do so.
- CAP_MAC_OVERRIDE = Cap(32)
-
- // Allow MAC configuration or state changes.
- // The base kernel requires no MAC configuration.
- // An LSM may enforce a MAC policy, and if it does and it chooses
- // to implement capability based checks on modifications to that
- // policy or the data required to maintain it, this is the
- // capability it should use to do so.
- CAP_MAC_ADMIN = Cap(33)
-
- // Allow configuring the kernel's syslog (printk behaviour)
- CAP_SYSLOG = Cap(34)
-
- // Allow triggering something that will wake the system
- CAP_WAKE_ALARM = Cap(35)
-
- // Allow preventing system suspends
- CAP_BLOCK_SUSPEND = Cap(36)
-
- // Allow reading audit messages from the kernel
- CAP_AUDIT_READ = Cap(37)
-)
-
-var (
- // Highest valid capability of the running kernel.
- CAP_LAST_CAP = Cap(63)
-
- capUpperMask = ^uint32(0)
-)
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/enum_gen.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/enum_gen.go
deleted file mode 100644
index b9e6d2d5..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/enum_gen.go
+++ /dev/null
@@ -1,129 +0,0 @@
-// generated file; DO NOT EDIT - use go generate in directory with source
-
-package capability
-
-func (c Cap) String() string {
- switch c {
- case CAP_CHOWN:
- return "chown"
- case CAP_DAC_OVERRIDE:
- return "dac_override"
- case CAP_DAC_READ_SEARCH:
- return "dac_read_search"
- case CAP_FOWNER:
- return "fowner"
- case CAP_FSETID:
- return "fsetid"
- case CAP_KILL:
- return "kill"
- case CAP_SETGID:
- return "setgid"
- case CAP_SETUID:
- return "setuid"
- case CAP_SETPCAP:
- return "setpcap"
- case CAP_LINUX_IMMUTABLE:
- return "linux_immutable"
- case CAP_NET_BIND_SERVICE:
- return "net_bind_service"
- case CAP_NET_BROADCAST:
- return "net_broadcast"
- case CAP_NET_ADMIN:
- return "net_admin"
- case CAP_NET_RAW:
- return "net_raw"
- case CAP_IPC_LOCK:
- return "ipc_lock"
- case CAP_IPC_OWNER:
- return "ipc_owner"
- case CAP_SYS_MODULE:
- return "sys_module"
- case CAP_SYS_RAWIO:
- return "sys_rawio"
- case CAP_SYS_CHROOT:
- return "sys_chroot"
- case CAP_SYS_PTRACE:
- return "sys_ptrace"
- case CAP_SYS_PACCT:
- return "sys_pacct"
- case CAP_SYS_ADMIN:
- return "sys_admin"
- case CAP_SYS_BOOT:
- return "sys_boot"
- case CAP_SYS_NICE:
- return "sys_nice"
- case CAP_SYS_RESOURCE:
- return "sys_resource"
- case CAP_SYS_TIME:
- return "sys_time"
- case CAP_SYS_TTY_CONFIG:
- return "sys_tty_config"
- case CAP_MKNOD:
- return "mknod"
- case CAP_LEASE:
- return "lease"
- case CAP_AUDIT_WRITE:
- return "audit_write"
- case CAP_AUDIT_CONTROL:
- return "audit_control"
- case CAP_SETFCAP:
- return "setfcap"
- case CAP_MAC_OVERRIDE:
- return "mac_override"
- case CAP_MAC_ADMIN:
- return "mac_admin"
- case CAP_SYSLOG:
- return "syslog"
- case CAP_WAKE_ALARM:
- return "wake_alarm"
- case CAP_BLOCK_SUSPEND:
- return "block_suspend"
- case CAP_AUDIT_READ:
- return "audit_read"
- }
- return "unknown"
-}
-
-// List returns list of all supported capabilities
-func List() []Cap {
- return []Cap{
- CAP_CHOWN,
- CAP_DAC_OVERRIDE,
- CAP_DAC_READ_SEARCH,
- CAP_FOWNER,
- CAP_FSETID,
- CAP_KILL,
- CAP_SETGID,
- CAP_SETUID,
- CAP_SETPCAP,
- CAP_LINUX_IMMUTABLE,
- CAP_NET_BIND_SERVICE,
- CAP_NET_BROADCAST,
- CAP_NET_ADMIN,
- CAP_NET_RAW,
- CAP_IPC_LOCK,
- CAP_IPC_OWNER,
- CAP_SYS_MODULE,
- CAP_SYS_RAWIO,
- CAP_SYS_CHROOT,
- CAP_SYS_PTRACE,
- CAP_SYS_PACCT,
- CAP_SYS_ADMIN,
- CAP_SYS_BOOT,
- CAP_SYS_NICE,
- CAP_SYS_RESOURCE,
- CAP_SYS_TIME,
- CAP_SYS_TTY_CONFIG,
- CAP_MKNOD,
- CAP_LEASE,
- CAP_AUDIT_WRITE,
- CAP_AUDIT_CONTROL,
- CAP_SETFCAP,
- CAP_MAC_OVERRIDE,
- CAP_MAC_ADMIN,
- CAP_SYSLOG,
- CAP_WAKE_ALARM,
- CAP_BLOCK_SUSPEND,
- CAP_AUDIT_READ,
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/enumgen/gen.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/enumgen/gen.go
deleted file mode 100644
index 4c733809..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/enumgen/gen.go
+++ /dev/null
@@ -1,92 +0,0 @@
-package main
-
-import (
- "bytes"
- "fmt"
- "go/ast"
- "go/format"
- "go/parser"
- "go/token"
- "io/ioutil"
- "log"
- "os"
- "strings"
-)
-
-const fileName = "enum.go"
-const genName = "enum_gen.go"
-
-type generator struct {
- buf bytes.Buffer
- caps []string
-}
-
-func (g *generator) writeHeader() {
- g.buf.WriteString("// generated file; DO NOT EDIT - use go generate in directory with source\n")
- g.buf.WriteString("\n")
- g.buf.WriteString("package capability")
-}
-
-func (g *generator) writeStringFunc() {
- g.buf.WriteString("\n")
- g.buf.WriteString("func (c Cap) String() string {\n")
- g.buf.WriteString("switch c {\n")
- for _, cap := range g.caps {
- fmt.Fprintf(&g.buf, "case %s:\n", cap)
- fmt.Fprintf(&g.buf, "return \"%s\"\n", strings.ToLower(cap[4:]))
- }
- g.buf.WriteString("}\n")
- g.buf.WriteString("return \"unknown\"\n")
- g.buf.WriteString("}\n")
-}
-
-func (g *generator) writeListFunc() {
- g.buf.WriteString("\n")
- g.buf.WriteString("// List returns list of all supported capabilities\n")
- g.buf.WriteString("func List() []Cap {\n")
- g.buf.WriteString("return []Cap{\n")
- for _, cap := range g.caps {
- fmt.Fprintf(&g.buf, "%s,\n", cap)
- }
- g.buf.WriteString("}\n")
- g.buf.WriteString("}\n")
-}
-
-func main() {
- fs := token.NewFileSet()
- parsedFile, err := parser.ParseFile(fs, fileName, nil, 0)
- if err != nil {
- log.Fatal(err)
- }
- var caps []string
- for _, decl := range parsedFile.Decls {
- decl, ok := decl.(*ast.GenDecl)
- if !ok || decl.Tok != token.CONST {
- continue
- }
- for _, spec := range decl.Specs {
- vspec := spec.(*ast.ValueSpec)
- name := vspec.Names[0].Name
- if strings.HasPrefix(name, "CAP_") {
- caps = append(caps, name)
- }
- }
- }
- g := &generator{caps: caps}
- g.writeHeader()
- g.writeStringFunc()
- g.writeListFunc()
- src, err := format.Source(g.buf.Bytes())
- if err != nil {
- fmt.Println("generated invalid Go code")
- fmt.Println(g.buf.String())
- log.Fatal(err)
- }
- fi, err := os.Stat(fileName)
- if err != nil {
- log.Fatal(err)
- }
- if err := ioutil.WriteFile(genName, src, fi.Mode().Perm()); err != nil {
- log.Fatal(err)
- }
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/syscall_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/syscall_linux.go
deleted file mode 100644
index dd6f4540..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/syndtr/gocapability/capability/syscall_linux.go
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright (c) 2013, Suryandaru Triandana
-// All rights reserved.
-//
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package capability
-
-import (
- "syscall"
- "unsafe"
-)
-
-type capHeader struct {
- version uint32
- pid int
-}
-
-type capData struct {
- effective uint32
- permitted uint32
- inheritable uint32
-}
-
-func capget(hdr *capHeader, data *capData) (err error) {
- _, _, e1 := syscall.Syscall(syscall.SYS_CAPGET, uintptr(unsafe.Pointer(hdr)), uintptr(unsafe.Pointer(data)), 0)
- if e1 != 0 {
- err = e1
- }
- return
-}
-
-func capset(hdr *capHeader, data *capData) (err error) {
- _, _, e1 := syscall.Syscall(syscall.SYS_CAPSET, uintptr(unsafe.Pointer(hdr)), uintptr(unsafe.Pointer(data)), 0)
- if e1 != 0 {
- err = e1
- }
- return
-}
-
-func prctl(option int, arg2, arg3, arg4, arg5 uintptr) (err error) {
- _, _, e1 := syscall.Syscall6(syscall.SYS_PRCTL, uintptr(option), arg2, arg3, arg4, arg5, 0)
- if e1 != 0 {
- err = e1
- }
- return
-}
-
-const (
- vfsXattrName = "security.capability"
-
- vfsCapVerMask = 0xff000000
- vfsCapVer1 = 0x01000000
- vfsCapVer2 = 0x02000000
-
- vfsCapFlagMask = ^vfsCapVerMask
- vfsCapFlageffective = 0x000001
-
- vfscapDataSizeV1 = 4 * (1 + 2*1)
- vfscapDataSizeV2 = 4 * (1 + 2*2)
-)
-
-type vfscapData struct {
- magic uint32
- data [2]struct {
- permitted uint32
- inheritable uint32
- }
- effective [2]uint32
- version int8
-}
-
-var (
- _vfsXattrName *byte
-)
-
-func init() {
- _vfsXattrName, _ = syscall.BytePtrFromString(vfsXattrName)
-}
-
-func getVfsCap(path string, dest *vfscapData) (err error) {
- var _p0 *byte
- _p0, err = syscall.BytePtrFromString(path)
- if err != nil {
- return
- }
- r0, _, e1 := syscall.Syscall6(syscall.SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_vfsXattrName)), uintptr(unsafe.Pointer(dest)), vfscapDataSizeV2, 0, 0)
- if e1 != 0 {
- if e1 == syscall.ENODATA {
- dest.version = 2
- return
- }
- err = e1
- }
- switch dest.magic & vfsCapVerMask {
- case vfsCapVer1:
- dest.version = 1
- if r0 != vfscapDataSizeV1 {
- return syscall.EINVAL
- }
- dest.data[1].permitted = 0
- dest.data[1].inheritable = 0
- case vfsCapVer2:
- dest.version = 2
- if r0 != vfscapDataSizeV2 {
- return syscall.EINVAL
- }
- default:
- return syscall.EINVAL
- }
- if dest.magic&vfsCapFlageffective != 0 {
- dest.effective[0] = dest.data[0].permitted | dest.data[0].inheritable
- dest.effective[1] = dest.data[1].permitted | dest.data[1].inheritable
- } else {
- dest.effective[0] = 0
- dest.effective[1] = 0
- }
- return
-}
-
-func setVfsCap(path string, data *vfscapData) (err error) {
- var _p0 *byte
- _p0, err = syscall.BytePtrFromString(path)
- if err != nil {
- return
- }
- var size uintptr
- if data.version == 1 {
- data.magic = vfsCapVer1
- size = vfscapDataSizeV1
- } else if data.version == 2 {
- data.magic = vfsCapVer2
- if data.effective[0] != 0 || data.effective[1] != 0 {
- data.magic |= vfsCapFlageffective
- }
- size = vfscapDataSizeV2
- } else {
- return syscall.EINVAL
- }
- _, _, e1 := syscall.Syscall6(syscall.SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_vfsXattrName)), uintptr(unsafe.Pointer(data)), size, 0, 0)
- if e1 != 0 {
- err = e1
- }
- return
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/.travis.yml b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/.travis.yml
deleted file mode 100644
index 1970069d..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/.travis.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-language: go
-install:
- - go get github.com/vishvananda/netns
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/LICENSE b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/LICENSE
deleted file mode 100644
index 9f64db85..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/LICENSE
+++ /dev/null
@@ -1,192 +0,0 @@
-
- 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
-
- Copyright 2014 Vishvananda Ishaya.
- Copyright 2014 Docker, Inc.
-
- 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/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/Makefile b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/Makefile
deleted file mode 100644
index b3250185..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-DIRS := \
- . \
- nl
-
-DEPS = \
- github.com/vishvananda/netns
-
-uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
-testdirs = $(call uniq,$(foreach d,$(1),$(dir $(wildcard $(d)/*_test.go))))
-goroot = $(addprefix ../../../,$(1))
-unroot = $(subst ../../../,,$(1))
-fmt = $(addprefix fmt-,$(1))
-
-all: fmt
-
-$(call goroot,$(DEPS)):
- go get $(call unroot,$@)
-
-.PHONY: $(call testdirs,$(DIRS))
-$(call testdirs,$(DIRS)):
- sudo -E go test -v github.com/vishvananda/netlink/$@
-
-$(call fmt,$(call testdirs,$(DIRS))):
- ! gofmt -l $(subst fmt-,,$@)/*.go | grep ''
-
-.PHONY: fmt
-fmt: $(call fmt,$(call testdirs,$(DIRS)))
-
-test: fmt $(call goroot,$(DEPS)) $(call testdirs,$(DIRS))
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/README.md b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/README.md
deleted file mode 100644
index 8cd50a93..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/README.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# netlink - netlink library for go #
-
-[![Build Status](https://travis-ci.org/vishvananda/netlink.png?branch=master)](https://travis-ci.org/vishvananda/netlink) [![GoDoc](https://godoc.org/github.com/vishvananda/netlink?status.svg)](https://godoc.org/github.com/vishvananda/netlink)
-
-The netlink package provides a simple netlink library for go. Netlink
-is the interface a user-space program in linux uses to communicate with
-the kernel. It can be used to add and remove interfaces, set ip addresses
-and routes, and configure ipsec. Netlink communication requires elevated
-privileges, so in most cases this code needs to be run as root. Since
-low-level netlink messages are inscrutable at best, the library attempts
-to provide an api that is loosely modeled on the CLI provied by iproute2.
-Actions like `ip link add` will be accomplished via a similarly named
-function like AddLink(). This library began its life as a fork of the
-netlink functionality in
-[docker/libcontainer](https://github.com/docker/libcontainer) but was
-heavily rewritten to improve testability, performance, and to add new
-functionality like ipsec xfrm handling.
-
-## Local Build and Test ##
-
-You can use go get command:
-
- go get github.com/vishvananda/netlink
-
-Testing dependencies:
-
- go get github.com/vishvananda/netns
-
-Testing (requires root):
-
- sudo -E go test github.com/vishvananda/netlink
-
-## Examples ##
-
-Add a new bridge and add eth1 into it:
-
-```go
-package main
-
-import (
- "net"
- "github.com/vishvananda/netlink"
-)
-
-func main() {
- la := netlink.NewLinkAttrs()
- la.Name = "foo"
- mybridge := &netlink.Bridge{la}}
- _ := netlink.LinkAdd(mybridge)
- eth1, _ := netlink.LinkByName("eth1")
- netlink.LinkSetMaster(eth1, mybridge)
-}
-
-```
-Note `NewLinkAttrs` constructor, it sets default values in structure. For now
-it sets only `TxQLen` to `-1`, so kernel will set default by itself. If you're
-using simple initialization(`LinkAttrs{Name: "foo"}`) `TxQLen` will be set to
-`0` unless you specify it like `LinkAttrs{Name: "foo", TxQLen: 1000}`.
-
-Add a new ip address to loopback:
-
-```go
-package main
-
-import (
- "net"
- "github.com/vishvananda/netlink"
-)
-
-func main() {
- lo, _ := netlink.LinkByName("lo")
- addr, _ := netlink.ParseAddr("169.254.169.254/32")
- netlink.AddrAdd(lo, addr)
-}
-
-```
-
-## Future Work ##
-
-Many pieces of netlink are not yet fully supported in the high-level
-interface. Aspects of virtually all of the high-level objects don't exist.
-Many of the underlying primitives are there, so its a matter of putting
-the right fields into the high-level objects and making sure that they
-are serialized and deserialized correctly in the Add and List methods.
-
-There are also a few pieces of low level netlink functionality that still
-need to be implemented. Routing rules are not in place and some of the
-more advanced link types. Hopefully there is decent structure and testing
-in place to make these fairly straightforward to add.
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/addr.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/addr.go
deleted file mode 100644
index 9bbaf508..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/addr.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package netlink
-
-import (
- "fmt"
- "net"
- "strings"
-)
-
-// Addr represents an IP address from netlink. Netlink ip addresses
-// include a mask, so it stores the address as a net.IPNet.
-type Addr struct {
- *net.IPNet
- Label string
-}
-
-// String returns $ip/$netmask $label
-func (a Addr) String() string {
- return fmt.Sprintf("%s %s", a.IPNet, a.Label)
-}
-
-// ParseAddr parses the string representation of an address in the
-// form $ip/$netmask $label. The label portion is optional
-func ParseAddr(s string) (*Addr, error) {
- label := ""
- parts := strings.Split(s, " ")
- if len(parts) > 1 {
- s = parts[0]
- label = parts[1]
- }
- m, err := ParseIPNet(s)
- if err != nil {
- return nil, err
- }
- return &Addr{IPNet: m, Label: label}, nil
-}
-
-// Equal returns true if both Addrs have the same net.IPNet value.
-func (a Addr) Equal(x Addr) bool {
- sizea, _ := a.Mask.Size()
- sizeb, _ := x.Mask.Size()
- // ignore label for comparison
- return a.IP.Equal(x.IP) && sizea == sizeb
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/addr_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/addr_linux.go
deleted file mode 100644
index 19aac0fb..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/addr_linux.go
+++ /dev/null
@@ -1,128 +0,0 @@
-package netlink
-
-import (
- "fmt"
- "net"
- "strings"
- "syscall"
-
- "github.com/vishvananda/netlink/nl"
-)
-
-// AddrAdd will add an IP address to a link device.
-// Equivalent to: `ip addr add $addr dev $link`
-func AddrAdd(link Link, addr *Addr) error {
-
- req := nl.NewNetlinkRequest(syscall.RTM_NEWADDR, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
- return addrHandle(link, addr, req)
-}
-
-// AddrDel will delete an IP address from a link device.
-// Equivalent to: `ip addr del $addr dev $link`
-func AddrDel(link Link, addr *Addr) error {
- req := nl.NewNetlinkRequest(syscall.RTM_DELADDR, syscall.NLM_F_ACK)
- return addrHandle(link, addr, req)
-}
-
-func addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error {
- base := link.Attrs()
- if addr.Label != "" && !strings.HasPrefix(addr.Label, base.Name) {
- return fmt.Errorf("label must begin with interface name")
- }
- ensureIndex(base)
-
- family := nl.GetIPFamily(addr.IP)
-
- msg := nl.NewIfAddrmsg(family)
- msg.Index = uint32(base.Index)
- prefixlen, _ := addr.Mask.Size()
- msg.Prefixlen = uint8(prefixlen)
- req.AddData(msg)
-
- var addrData []byte
- if family == FAMILY_V4 {
- addrData = addr.IP.To4()
- } else {
- addrData = addr.IP.To16()
- }
-
- localData := nl.NewRtAttr(syscall.IFA_LOCAL, addrData)
- req.AddData(localData)
-
- addressData := nl.NewRtAttr(syscall.IFA_ADDRESS, addrData)
- req.AddData(addressData)
-
- if addr.Label != "" {
- labelData := nl.NewRtAttr(syscall.IFA_LABEL, nl.ZeroTerminated(addr.Label))
- req.AddData(labelData)
- }
-
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- return err
-}
-
-// AddrList gets a list of IP addresses in the system.
-// Equivalent to: `ip addr show`.
-// The list can be filtered by link and ip family.
-func AddrList(link Link, family int) ([]Addr, error) {
- req := nl.NewNetlinkRequest(syscall.RTM_GETADDR, syscall.NLM_F_DUMP)
- msg := nl.NewIfInfomsg(family)
- req.AddData(msg)
-
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWADDR)
- if err != nil {
- return nil, err
- }
-
- index := 0
- if link != nil {
- base := link.Attrs()
- ensureIndex(base)
- index = base.Index
- }
-
- var res []Addr
- for _, m := range msgs {
- msg := nl.DeserializeIfAddrmsg(m)
-
- if link != nil && msg.Index != uint32(index) {
- // Ignore messages from other interfaces
- continue
- }
-
- attrs, err := nl.ParseRouteAttr(m[msg.Len():])
- if err != nil {
- return nil, err
- }
-
- var local, dst *net.IPNet
- var addr Addr
- for _, attr := range attrs {
- switch attr.Attr.Type {
- case syscall.IFA_ADDRESS:
- dst = &net.IPNet{
- IP: attr.Value,
- Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
- }
- case syscall.IFA_LOCAL:
- local = &net.IPNet{
- IP: attr.Value,
- Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
- }
- case syscall.IFA_LABEL:
- addr.Label = string(attr.Value[:len(attr.Value)-1])
- }
- }
-
- // IFA_LOCAL should be there but if not, fall back to IFA_ADDRESS
- if local != nil {
- addr.IPNet = local
- } else {
- addr.IPNet = dst
- }
-
- res = append(res, addr)
- }
-
- return res, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/filter.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/filter.go
deleted file mode 100644
index 83ad7007..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/filter.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package netlink
-
-import (
- "fmt"
-)
-
-type Filter interface {
- Attrs() *FilterAttrs
- Type() string
-}
-
-// Filter represents a netlink filter. A filter is associated with a link,
-// has a handle and a parent. The root filter of a device should have a
-// parent == HANDLE_ROOT.
-type FilterAttrs struct {
- LinkIndex int
- Handle uint32
- Parent uint32
- Priority uint16 // lower is higher priority
- Protocol uint16 // syscall.ETH_P_*
-}
-
-func (q FilterAttrs) String() string {
- return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Priority: %d, Protocol: %d}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Priority, q.Protocol)
-}
-
-// U32 filters on many packet related properties
-type U32 struct {
- FilterAttrs
- // Currently only supports redirecting to another interface
- RedirIndex int
-}
-
-func (filter *U32) Attrs() *FilterAttrs {
- return &filter.FilterAttrs
-}
-
-func (filter *U32) Type() string {
- return "u32"
-}
-
-// GenericFilter filters represent types that are not currently understood
-// by this netlink library.
-type GenericFilter struct {
- FilterAttrs
- FilterType string
-}
-
-func (filter *GenericFilter) Attrs() *FilterAttrs {
- return &filter.FilterAttrs
-}
-
-func (filter *GenericFilter) Type() string {
- return filter.FilterType
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/filter_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/filter_linux.go
deleted file mode 100644
index 1ec69870..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/filter_linux.go
+++ /dev/null
@@ -1,191 +0,0 @@
-package netlink
-
-import (
- "fmt"
- "syscall"
-
- "github.com/vishvananda/netlink/nl"
-)
-
-// FilterDel will delete a filter from the system.
-// Equivalent to: `tc filter del $filter`
-func FilterDel(filter Filter) error {
- req := nl.NewNetlinkRequest(syscall.RTM_DELTFILTER, syscall.NLM_F_ACK)
- base := filter.Attrs()
- msg := &nl.TcMsg{
- Family: nl.FAMILY_ALL,
- Ifindex: int32(base.LinkIndex),
- Handle: base.Handle,
- Parent: base.Parent,
- Info: MakeHandle(base.Priority, nl.Swap16(base.Protocol)),
- }
- req.AddData(msg)
-
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- return err
-}
-
-// FilterAdd will add a filter to the system.
-// Equivalent to: `tc filter add $filter`
-func FilterAdd(filter Filter) error {
- req := nl.NewNetlinkRequest(syscall.RTM_NEWTFILTER, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
- base := filter.Attrs()
- msg := &nl.TcMsg{
- Family: nl.FAMILY_ALL,
- Ifindex: int32(base.LinkIndex),
- Handle: base.Handle,
- Parent: base.Parent,
- Info: MakeHandle(base.Priority, nl.Swap16(base.Protocol)),
- }
- req.AddData(msg)
- req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(filter.Type())))
-
- options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)
- if u32, ok := filter.(*U32); ok {
- // match all
- sel := nl.TcU32Sel{
- Nkeys: 1,
- Flags: nl.TC_U32_TERMINAL,
- }
- sel.Keys = append(sel.Keys, nl.TcU32Key{})
- nl.NewRtAttrChild(options, nl.TCA_U32_SEL, sel.Serialize())
- actions := nl.NewRtAttrChild(options, nl.TCA_U32_ACT, nil)
- table := nl.NewRtAttrChild(actions, nl.TCA_ACT_TAB, nil)
- nl.NewRtAttrChild(table, nl.TCA_KIND, nl.ZeroTerminated("mirred"))
- // redirect to other interface
- mir := nl.TcMirred{
- Action: nl.TC_ACT_STOLEN,
- Eaction: nl.TCA_EGRESS_REDIR,
- Ifindex: uint32(u32.RedirIndex),
- }
- aopts := nl.NewRtAttrChild(table, nl.TCA_OPTIONS, nil)
- nl.NewRtAttrChild(aopts, nl.TCA_MIRRED_PARMS, mir.Serialize())
- }
- req.AddData(options)
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- return err
-}
-
-// FilterList gets a list of filters in the system.
-// Equivalent to: `tc filter show`.
-// Generally retunrs nothing if link and parent are not specified.
-func FilterList(link Link, parent uint32) ([]Filter, error) {
- req := nl.NewNetlinkRequest(syscall.RTM_GETTFILTER, syscall.NLM_F_DUMP)
- msg := &nl.TcMsg{
- Family: nl.FAMILY_ALL,
- Parent: parent,
- }
- if link != nil {
- base := link.Attrs()
- ensureIndex(base)
- msg.Ifindex = int32(base.Index)
- }
- req.AddData(msg)
-
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWTFILTER)
- if err != nil {
- return nil, err
- }
-
- var res []Filter
- for _, m := range msgs {
- msg := nl.DeserializeTcMsg(m)
-
- attrs, err := nl.ParseRouteAttr(m[msg.Len():])
- if err != nil {
- return nil, err
- }
-
- base := FilterAttrs{
- LinkIndex: int(msg.Ifindex),
- Handle: msg.Handle,
- Parent: msg.Parent,
- }
- base.Priority, base.Protocol = MajorMinor(msg.Info)
- base.Protocol = nl.Swap16(base.Protocol)
-
- var filter Filter
- filterType := ""
- detailed := false
- for _, attr := range attrs {
- switch attr.Attr.Type {
- case nl.TCA_KIND:
- filterType = string(attr.Value[:len(attr.Value)-1])
- switch filterType {
- case "u32":
- filter = &U32{}
- default:
- filter = &GenericFilter{FilterType: filterType}
- }
- case nl.TCA_OPTIONS:
- switch filterType {
- case "u32":
- data, err := nl.ParseRouteAttr(attr.Value)
- if err != nil {
- return nil, err
- }
- detailed, err = parseU32Data(filter, data)
- if err != nil {
- return nil, err
- }
- }
- }
- }
- // only return the detailed version of the filter
- if detailed {
- *filter.Attrs() = base
- res = append(res, filter)
- }
- }
-
- return res, nil
-}
-
-func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
- native = nl.NativeEndian()
- u32 := filter.(*U32)
- detailed := false
- for _, datum := range data {
- switch datum.Attr.Type {
- case nl.TCA_U32_SEL:
- detailed = true
- sel := nl.DeserializeTcU32Sel(datum.Value)
- // only parse if we have a very basic redirect
- if sel.Flags&nl.TC_U32_TERMINAL == 0 || sel.Nkeys != 1 {
- return detailed, nil
- }
- case nl.TCA_U32_ACT:
- table, err := nl.ParseRouteAttr(datum.Value)
- if err != nil {
- return detailed, err
- }
- if len(table) != 1 || table[0].Attr.Type != nl.TCA_ACT_TAB {
- return detailed, fmt.Errorf("Action table not formed properly")
- }
- aattrs, err := nl.ParseRouteAttr(table[0].Value)
- for _, aattr := range aattrs {
- switch aattr.Attr.Type {
- case nl.TCA_KIND:
- actionType := string(aattr.Value[:len(aattr.Value)-1])
- // only parse if the action is mirred
- if actionType != "mirred" {
- return detailed, nil
- }
- case nl.TCA_OPTIONS:
- adata, err := nl.ParseRouteAttr(aattr.Value)
- if err != nil {
- return detailed, err
- }
- for _, adatum := range adata {
- switch adatum.Attr.Type {
- case nl.TCA_MIRRED_PARMS:
- mir := nl.DeserializeTcMirred(adatum.Value)
- u32.RedirIndex = int(mir.Ifindex)
- }
- }
- }
- }
- }
- }
- return detailed, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/link.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/link.go
deleted file mode 100644
index 18fd1759..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/link.go
+++ /dev/null
@@ -1,223 +0,0 @@
-package netlink
-
-import "net"
-
-// Link represents a link device from netlink. Shared link attributes
-// like name may be retrieved using the Attrs() method. Unique data
-// can be retrieved by casting the object to the proper type.
-type Link interface {
- Attrs() *LinkAttrs
- Type() string
-}
-
-type (
- NsPid int
- NsFd int
-)
-
-// LinkAttrs represents data shared by most link types
-type LinkAttrs struct {
- Index int
- MTU int
- TxQLen int // Transmit Queue Length
- Name string
- HardwareAddr net.HardwareAddr
- Flags net.Flags
- ParentIndex int // index of the parent link device
- MasterIndex int // must be the index of a bridge
- Namespace interface{} // nil | NsPid | NsFd
-}
-
-// NewLinkAttrs returns LinkAttrs structure filled with default values
-func NewLinkAttrs() LinkAttrs {
- return LinkAttrs{
- TxQLen: -1,
- }
-}
-
-// Device links cannot be created via netlink. These links
-// are links created by udev like 'lo' and 'etho0'
-type Device struct {
- LinkAttrs
-}
-
-func (device *Device) Attrs() *LinkAttrs {
- return &device.LinkAttrs
-}
-
-func (device *Device) Type() string {
- return "device"
-}
-
-// Dummy links are dummy ethernet devices
-type Dummy struct {
- LinkAttrs
-}
-
-func (dummy *Dummy) Attrs() *LinkAttrs {
- return &dummy.LinkAttrs
-}
-
-func (dummy *Dummy) Type() string {
- return "dummy"
-}
-
-// Ifb links are advanced dummy devices for packet filtering
-type Ifb struct {
- LinkAttrs
-}
-
-func (ifb *Ifb) Attrs() *LinkAttrs {
- return &ifb.LinkAttrs
-}
-
-func (ifb *Ifb) Type() string {
- return "ifb"
-}
-
-// Bridge links are simple linux bridges
-type Bridge struct {
- LinkAttrs
-}
-
-func (bridge *Bridge) Attrs() *LinkAttrs {
- return &bridge.LinkAttrs
-}
-
-func (bridge *Bridge) Type() string {
- return "bridge"
-}
-
-// Vlan links have ParentIndex set in their Attrs()
-type Vlan struct {
- LinkAttrs
- VlanId int
-}
-
-func (vlan *Vlan) Attrs() *LinkAttrs {
- return &vlan.LinkAttrs
-}
-
-func (vlan *Vlan) Type() string {
- return "vlan"
-}
-
-type MacvlanMode uint16
-
-const (
- MACVLAN_MODE_DEFAULT MacvlanMode = iota
- MACVLAN_MODE_PRIVATE
- MACVLAN_MODE_VEPA
- MACVLAN_MODE_BRIDGE
- MACVLAN_MODE_PASSTHRU
- MACVLAN_MODE_SOURCE
-)
-
-// Macvlan links have ParentIndex set in their Attrs()
-type Macvlan struct {
- LinkAttrs
- Mode MacvlanMode
-}
-
-func (macvlan *Macvlan) Attrs() *LinkAttrs {
- return &macvlan.LinkAttrs
-}
-
-func (macvlan *Macvlan) Type() string {
- return "macvlan"
-}
-
-// Macvtap - macvtap is a virtual interfaces based on macvlan
-type Macvtap struct {
- Macvlan
-}
-
-func (macvtap Macvtap) Type() string {
- return "macvtap"
-}
-
-// Veth devices must specify PeerName on create
-type Veth struct {
- LinkAttrs
- PeerName string // veth on create only
-}
-
-func (veth *Veth) Attrs() *LinkAttrs {
- return &veth.LinkAttrs
-}
-
-func (veth *Veth) Type() string {
- return "veth"
-}
-
-// GenericLink links represent types that are not currently understood
-// by this netlink library.
-type GenericLink struct {
- LinkAttrs
- LinkType string
-}
-
-func (generic *GenericLink) Attrs() *LinkAttrs {
- return &generic.LinkAttrs
-}
-
-func (generic *GenericLink) Type() string {
- return generic.LinkType
-}
-
-type Vxlan struct {
- LinkAttrs
- VxlanId int
- VtepDevIndex int
- SrcAddr net.IP
- Group net.IP
- TTL int
- TOS int
- Learning bool
- Proxy bool
- RSC bool
- L2miss bool
- L3miss bool
- NoAge bool
- GBP bool
- Age int
- Limit int
- Port int
- PortLow int
- PortHigh int
-}
-
-func (vxlan *Vxlan) Attrs() *LinkAttrs {
- return &vxlan.LinkAttrs
-}
-
-func (vxlan *Vxlan) Type() string {
- return "vxlan"
-}
-
-type IPVlanMode uint16
-
-const (
- IPVLAN_MODE_L2 IPVlanMode = iota
- IPVLAN_MODE_L3
- IPVLAN_MODE_MAX
-)
-
-type IPVlan struct {
- LinkAttrs
- Mode IPVlanMode
-}
-
-func (ipvlan *IPVlan) Attrs() *LinkAttrs {
- return &ipvlan.LinkAttrs
-}
-
-func (ipvlan *IPVlan) Type() string {
- return "ipvlan"
-}
-
-// iproute2 supported devices;
-// vlan | veth | vcan | dummy | ifb | macvlan | macvtap |
-// bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan |
-// gre | gretap | ip6gre | ip6gretap | vti | nlmon |
-// bond_slave | ipvlan
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/link_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/link_linux.go
deleted file mode 100644
index 68511504..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/link_linux.go
+++ /dev/null
@@ -1,750 +0,0 @@
-package netlink
-
-import (
- "bytes"
- "encoding/binary"
- "fmt"
- "net"
- "syscall"
-
- "github.com/vishvananda/netlink/nl"
-)
-
-var native = nl.NativeEndian()
-var lookupByDump = false
-
-var macvlanModes = [...]uint32{
- 0,
- nl.MACVLAN_MODE_PRIVATE,
- nl.MACVLAN_MODE_VEPA,
- nl.MACVLAN_MODE_BRIDGE,
- nl.MACVLAN_MODE_PASSTHRU,
- nl.MACVLAN_MODE_SOURCE,
-}
-
-func ensureIndex(link *LinkAttrs) {
- if link != nil && link.Index == 0 {
- newlink, _ := LinkByName(link.Name)
- if newlink != nil {
- link.Index = newlink.Attrs().Index
- }
- }
-}
-
-// LinkSetUp enables the link device.
-// Equivalent to: `ip link set $link up`
-func LinkSetUp(link Link) error {
- base := link.Attrs()
- ensureIndex(base)
- req := nl.NewNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK)
-
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
- msg.Change = syscall.IFF_UP
- msg.Flags = syscall.IFF_UP
- msg.Index = int32(base.Index)
- req.AddData(msg)
-
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- return err
-}
-
-// LinkSetDown disables link device.
-// Equivalent to: `ip link set $link down`
-func LinkSetDown(link Link) error {
- base := link.Attrs()
- ensureIndex(base)
- req := nl.NewNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK)
-
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
- msg.Change = syscall.IFF_UP
- msg.Flags = 0 & ^syscall.IFF_UP
- msg.Index = int32(base.Index)
- req.AddData(msg)
-
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- return err
-}
-
-// LinkSetMTU sets the mtu of the link device.
-// Equivalent to: `ip link set $link mtu $mtu`
-func LinkSetMTU(link Link, mtu int) error {
- base := link.Attrs()
- ensureIndex(base)
- req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
-
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
- msg.Index = int32(base.Index)
- req.AddData(msg)
-
- b := make([]byte, 4)
- native.PutUint32(b, uint32(mtu))
-
- data := nl.NewRtAttr(syscall.IFLA_MTU, b)
- req.AddData(data)
-
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- return err
-}
-
-// LinkSetName sets the name of the link device.
-// Equivalent to: `ip link set $link name $name`
-func LinkSetName(link Link, name string) error {
- base := link.Attrs()
- ensureIndex(base)
- req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
-
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
- msg.Index = int32(base.Index)
- req.AddData(msg)
-
- data := nl.NewRtAttr(syscall.IFLA_IFNAME, []byte(name))
- req.AddData(data)
-
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- return err
-}
-
-// LinkSetHardwareAddr sets the hardware address of the link device.
-// Equivalent to: `ip link set $link address $hwaddr`
-func LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error {
- base := link.Attrs()
- ensureIndex(base)
- req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
-
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
- msg.Index = int32(base.Index)
- req.AddData(msg)
-
- data := nl.NewRtAttr(syscall.IFLA_ADDRESS, []byte(hwaddr))
- req.AddData(data)
-
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- return err
-}
-
-// LinkSetMaster sets the master of the link device.
-// Equivalent to: `ip link set $link master $master`
-func LinkSetMaster(link Link, master *Bridge) error {
- index := 0
- if master != nil {
- masterBase := master.Attrs()
- ensureIndex(masterBase)
- index = masterBase.Index
- }
- return LinkSetMasterByIndex(link, index)
-}
-
-// LinkSetMasterByIndex sets the master of the link device.
-// Equivalent to: `ip link set $link master $master`
-func LinkSetMasterByIndex(link Link, masterIndex int) error {
- base := link.Attrs()
- ensureIndex(base)
- req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
-
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
- msg.Index = int32(base.Index)
- req.AddData(msg)
-
- b := make([]byte, 4)
- native.PutUint32(b, uint32(masterIndex))
-
- data := nl.NewRtAttr(syscall.IFLA_MASTER, b)
- req.AddData(data)
-
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- return err
-}
-
-// LinkSetNsPid puts the device into a new network namespace. The
-// pid must be a pid of a running process.
-// Equivalent to: `ip link set $link netns $pid`
-func LinkSetNsPid(link Link, nspid int) error {
- base := link.Attrs()
- ensureIndex(base)
- req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
-
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
- msg.Index = int32(base.Index)
- req.AddData(msg)
-
- b := make([]byte, 4)
- native.PutUint32(b, uint32(nspid))
-
- data := nl.NewRtAttr(syscall.IFLA_NET_NS_PID, b)
- req.AddData(data)
-
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- return err
-}
-
-// LinkSetNsFd puts the device into a new network namespace. The
-// fd must be an open file descriptor to a network namespace.
-// Similar to: `ip link set $link netns $ns`
-func LinkSetNsFd(link Link, fd int) error {
- base := link.Attrs()
- ensureIndex(base)
- req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
-
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
- msg.Index = int32(base.Index)
- req.AddData(msg)
-
- b := make([]byte, 4)
- native.PutUint32(b, uint32(fd))
-
- data := nl.NewRtAttr(nl.IFLA_NET_NS_FD, b)
- req.AddData(data)
-
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- return err
-}
-
-func boolAttr(val bool) []byte {
- var v uint8
- if val {
- v = 1
- }
- return nl.Uint8Attr(v)
-}
-
-type vxlanPortRange struct {
- Lo, Hi uint16
-}
-
-func addVxlanAttrs(vxlan *Vxlan, linkInfo *nl.RtAttr) {
- data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_ID, nl.Uint32Attr(uint32(vxlan.VxlanId)))
- if vxlan.VtepDevIndex != 0 {
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_LINK, nl.Uint32Attr(uint32(vxlan.VtepDevIndex)))
- }
- if vxlan.SrcAddr != nil {
- ip := vxlan.SrcAddr.To4()
- if ip != nil {
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_LOCAL, []byte(ip))
- } else {
- ip = vxlan.SrcAddr.To16()
- if ip != nil {
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_LOCAL6, []byte(ip))
- }
- }
- }
- if vxlan.Group != nil {
- group := vxlan.Group.To4()
- if group != nil {
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_GROUP, []byte(group))
- } else {
- group = vxlan.Group.To16()
- if group != nil {
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_GROUP6, []byte(group))
- }
- }
- }
-
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_TTL, nl.Uint8Attr(uint8(vxlan.TTL)))
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_TOS, nl.Uint8Attr(uint8(vxlan.TOS)))
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_LEARNING, boolAttr(vxlan.Learning))
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_PROXY, boolAttr(vxlan.Proxy))
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_RSC, boolAttr(vxlan.RSC))
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_L2MISS, boolAttr(vxlan.L2miss))
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_L3MISS, boolAttr(vxlan.L3miss))
-
- if vxlan.GBP {
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_GBP, boolAttr(vxlan.GBP))
- }
-
- if vxlan.NoAge {
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_AGEING, nl.Uint32Attr(0))
- } else if vxlan.Age > 0 {
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_AGEING, nl.Uint32Attr(uint32(vxlan.Age)))
- }
- if vxlan.Limit > 0 {
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_LIMIT, nl.Uint32Attr(uint32(vxlan.Limit)))
- }
- if vxlan.Port > 0 {
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_PORT, nl.Uint16Attr(uint16(vxlan.Port)))
- }
- if vxlan.PortLow > 0 || vxlan.PortHigh > 0 {
- pr := vxlanPortRange{uint16(vxlan.PortLow), uint16(vxlan.PortHigh)}
-
- buf := new(bytes.Buffer)
- binary.Write(buf, binary.BigEndian, &pr)
-
- nl.NewRtAttrChild(data, nl.IFLA_VXLAN_PORT_RANGE, buf.Bytes())
- }
-}
-
-// LinkAdd adds a new link device. The type and features of the device
-// are taken fromt the parameters in the link object.
-// Equivalent to: `ip link add $link`
-func LinkAdd(link Link) error {
- // TODO: set mtu and hardware address
- // TODO: support extra data for macvlan
- base := link.Attrs()
-
- if base.Name == "" {
- return fmt.Errorf("LinkAttrs.Name cannot be empty!")
- }
-
- req := nl.NewNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
-
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
- req.AddData(msg)
-
- if base.ParentIndex != 0 {
- b := make([]byte, 4)
- native.PutUint32(b, uint32(base.ParentIndex))
- data := nl.NewRtAttr(syscall.IFLA_LINK, b)
- req.AddData(data)
- } else if link.Type() == "ipvlan" {
- return fmt.Errorf("Can't create ipvlan link without ParentIndex")
- }
-
- nameData := nl.NewRtAttr(syscall.IFLA_IFNAME, nl.ZeroTerminated(base.Name))
- req.AddData(nameData)
-
- if base.MTU > 0 {
- mtu := nl.NewRtAttr(syscall.IFLA_MTU, nl.Uint32Attr(uint32(base.MTU)))
- req.AddData(mtu)
- }
-
- if base.TxQLen >= 0 {
- qlen := nl.NewRtAttr(syscall.IFLA_TXQLEN, nl.Uint32Attr(uint32(base.TxQLen)))
- req.AddData(qlen)
- }
-
- if base.Namespace != nil {
- var attr *nl.RtAttr
- switch base.Namespace.(type) {
- case NsPid:
- val := nl.Uint32Attr(uint32(base.Namespace.(NsPid)))
- attr = nl.NewRtAttr(syscall.IFLA_NET_NS_PID, val)
- case NsFd:
- val := nl.Uint32Attr(uint32(base.Namespace.(NsFd)))
- attr = nl.NewRtAttr(nl.IFLA_NET_NS_FD, val)
- }
-
- req.AddData(attr)
- }
-
- linkInfo := nl.NewRtAttr(syscall.IFLA_LINKINFO, nil)
- nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_KIND, nl.NonZeroTerminated(link.Type()))
-
- if vlan, ok := link.(*Vlan); ok {
- b := make([]byte, 2)
- native.PutUint16(b, uint16(vlan.VlanId))
- data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
- nl.NewRtAttrChild(data, nl.IFLA_VLAN_ID, b)
- } else if veth, ok := link.(*Veth); ok {
- data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
- peer := nl.NewRtAttrChild(data, nl.VETH_INFO_PEER, nil)
- nl.NewIfInfomsgChild(peer, syscall.AF_UNSPEC)
- nl.NewRtAttrChild(peer, syscall.IFLA_IFNAME, nl.ZeroTerminated(veth.PeerName))
- if base.TxQLen >= 0 {
- nl.NewRtAttrChild(peer, syscall.IFLA_TXQLEN, nl.Uint32Attr(uint32(base.TxQLen)))
- }
- if base.MTU > 0 {
- nl.NewRtAttrChild(peer, syscall.IFLA_MTU, nl.Uint32Attr(uint32(base.MTU)))
- }
-
- } else if vxlan, ok := link.(*Vxlan); ok {
- addVxlanAttrs(vxlan, linkInfo)
- } else if ipv, ok := link.(*IPVlan); ok {
- data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
- nl.NewRtAttrChild(data, nl.IFLA_IPVLAN_MODE, nl.Uint16Attr(uint16(ipv.Mode)))
- } else if macv, ok := link.(*Macvlan); ok {
- if macv.Mode != MACVLAN_MODE_DEFAULT {
- data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
- nl.NewRtAttrChild(data, nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[macv.Mode]))
- }
- }
-
- req.AddData(linkInfo)
-
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- if err != nil {
- return err
- }
-
- ensureIndex(base)
-
- // can't set master during create, so set it afterwards
- if base.MasterIndex != 0 {
- // TODO: verify MasterIndex is actually a bridge?
- return LinkSetMasterByIndex(link, base.MasterIndex)
- }
- return nil
-}
-
-// LinkDel deletes link device. Either Index or Name must be set in
-// the link object for it to be deleted. The other values are ignored.
-// Equivalent to: `ip link del $link`
-func LinkDel(link Link) error {
- base := link.Attrs()
-
- ensureIndex(base)
-
- req := nl.NewNetlinkRequest(syscall.RTM_DELLINK, syscall.NLM_F_ACK)
-
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
- msg.Index = int32(base.Index)
- req.AddData(msg)
-
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- return err
-}
-
-func linkByNameDump(name string) (Link, error) {
- links, err := LinkList()
- if err != nil {
- return nil, err
- }
-
- for _, link := range links {
- if link.Attrs().Name == name {
- return link, nil
- }
- }
- return nil, fmt.Errorf("Link %s not found", name)
-}
-
-// LinkByName finds a link by name and returns a pointer to the object.
-func LinkByName(name string) (Link, error) {
- if lookupByDump {
- return linkByNameDump(name)
- }
-
- req := nl.NewNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_ACK)
-
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
- req.AddData(msg)
-
- nameData := nl.NewRtAttr(syscall.IFLA_IFNAME, nl.ZeroTerminated(name))
- req.AddData(nameData)
-
- link, err := execGetLink(req)
- if err == syscall.EINVAL {
- // older kernels don't support looking up via IFLA_IFNAME
- // so fall back to dumping all links
- lookupByDump = true
- return linkByNameDump(name)
- }
-
- return link, err
-}
-
-// LinkByIndex finds a link by index and returns a pointer to the object.
-func LinkByIndex(index int) (Link, error) {
- req := nl.NewNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_ACK)
-
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
- msg.Index = int32(index)
- req.AddData(msg)
-
- return execGetLink(req)
-}
-
-func execGetLink(req *nl.NetlinkRequest) (Link, error) {
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- if err != nil {
- if errno, ok := err.(syscall.Errno); ok {
- if errno == syscall.ENODEV {
- return nil, fmt.Errorf("Link not found")
- }
- }
- return nil, err
- }
-
- switch {
- case len(msgs) == 0:
- return nil, fmt.Errorf("Link not found")
-
- case len(msgs) == 1:
- return linkDeserialize(msgs[0])
-
- default:
- return nil, fmt.Errorf("More than one link found")
- }
-}
-
-// linkDeserialize deserializes a raw message received from netlink into
-// a link object.
-func linkDeserialize(m []byte) (Link, error) {
- msg := nl.DeserializeIfInfomsg(m)
-
- attrs, err := nl.ParseRouteAttr(m[msg.Len():])
- if err != nil {
- return nil, err
- }
-
- base := LinkAttrs{Index: int(msg.Index), Flags: linkFlags(msg.Flags)}
- var link Link
- linkType := ""
- for _, attr := range attrs {
- switch attr.Attr.Type {
- case syscall.IFLA_LINKINFO:
- infos, err := nl.ParseRouteAttr(attr.Value)
- if err != nil {
- return nil, err
- }
- for _, info := range infos {
- switch info.Attr.Type {
- case nl.IFLA_INFO_KIND:
- linkType = string(info.Value[:len(info.Value)-1])
- switch linkType {
- case "dummy":
- link = &Dummy{}
- case "ifb":
- link = &Ifb{}
- case "bridge":
- link = &Bridge{}
- case "vlan":
- link = &Vlan{}
- case "veth":
- link = &Veth{}
- case "vxlan":
- link = &Vxlan{}
- case "ipvlan":
- link = &IPVlan{}
- case "macvlan":
- link = &Macvlan{}
- case "macvtap":
- link = &Macvtap{}
- default:
- link = &GenericLink{LinkType: linkType}
- }
- case nl.IFLA_INFO_DATA:
- data, err := nl.ParseRouteAttr(info.Value)
- if err != nil {
- return nil, err
- }
- switch linkType {
- case "vlan":
- parseVlanData(link, data)
- case "vxlan":
- parseVxlanData(link, data)
- case "ipvlan":
- parseIPVlanData(link, data)
- case "macvlan":
- parseMacvlanData(link, data)
- case "macvtap":
- parseMacvtapData(link, data)
- }
- }
- }
- case syscall.IFLA_ADDRESS:
- var nonzero bool
- for _, b := range attr.Value {
- if b != 0 {
- nonzero = true
- }
- }
- if nonzero {
- base.HardwareAddr = attr.Value[:]
- }
- case syscall.IFLA_IFNAME:
- base.Name = string(attr.Value[:len(attr.Value)-1])
- case syscall.IFLA_MTU:
- base.MTU = int(native.Uint32(attr.Value[0:4]))
- case syscall.IFLA_LINK:
- base.ParentIndex = int(native.Uint32(attr.Value[0:4]))
- case syscall.IFLA_MASTER:
- base.MasterIndex = int(native.Uint32(attr.Value[0:4]))
- case syscall.IFLA_TXQLEN:
- base.TxQLen = int(native.Uint32(attr.Value[0:4]))
- }
- }
- // Links that don't have IFLA_INFO_KIND are hardware devices
- if link == nil {
- link = &Device{}
- }
- *link.Attrs() = base
-
- return link, nil
-}
-
-// LinkList gets a list of link devices.
-// Equivalent to: `ip link show`
-func LinkList() ([]Link, error) {
- // NOTE(vish): This duplicates functionality in net/iface_linux.go, but we need
- // to get the message ourselves to parse link type.
- req := nl.NewNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_DUMP)
-
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
- req.AddData(msg)
-
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWLINK)
- if err != nil {
- return nil, err
- }
-
- var res []Link
- for _, m := range msgs {
- link, err := linkDeserialize(m)
- if err != nil {
- return nil, err
- }
- res = append(res, link)
- }
-
- return res, nil
-}
-
-func LinkSetHairpin(link Link, mode bool) error {
- return setProtinfoAttr(link, mode, nl.IFLA_BRPORT_MODE)
-}
-
-func LinkSetGuard(link Link, mode bool) error {
- return setProtinfoAttr(link, mode, nl.IFLA_BRPORT_GUARD)
-}
-
-func LinkSetFastLeave(link Link, mode bool) error {
- return setProtinfoAttr(link, mode, nl.IFLA_BRPORT_FAST_LEAVE)
-}
-
-func LinkSetLearning(link Link, mode bool) error {
- return setProtinfoAttr(link, mode, nl.IFLA_BRPORT_LEARNING)
-}
-
-func LinkSetRootBlock(link Link, mode bool) error {
- return setProtinfoAttr(link, mode, nl.IFLA_BRPORT_PROTECT)
-}
-
-func LinkSetFlood(link Link, mode bool) error {
- return setProtinfoAttr(link, mode, nl.IFLA_BRPORT_UNICAST_FLOOD)
-}
-
-func setProtinfoAttr(link Link, mode bool, attr int) error {
- base := link.Attrs()
- ensureIndex(base)
- req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
-
- msg := nl.NewIfInfomsg(syscall.AF_BRIDGE)
- msg.Index = int32(base.Index)
- req.AddData(msg)
-
- br := nl.NewRtAttr(syscall.IFLA_PROTINFO|syscall.NLA_F_NESTED, nil)
- nl.NewRtAttrChild(br, attr, boolToByte(mode))
- req.AddData(br)
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- if err != nil {
- return err
- }
- return nil
-}
-
-func parseVlanData(link Link, data []syscall.NetlinkRouteAttr) {
- vlan := link.(*Vlan)
- for _, datum := range data {
- switch datum.Attr.Type {
- case nl.IFLA_VLAN_ID:
- vlan.VlanId = int(native.Uint16(datum.Value[0:2]))
- }
- }
-}
-
-func parseVxlanData(link Link, data []syscall.NetlinkRouteAttr) {
- vxlan := link.(*Vxlan)
- for _, datum := range data {
- switch datum.Attr.Type {
- case nl.IFLA_VXLAN_ID:
- vxlan.VxlanId = int(native.Uint32(datum.Value[0:4]))
- case nl.IFLA_VXLAN_LINK:
- vxlan.VtepDevIndex = int(native.Uint32(datum.Value[0:4]))
- case nl.IFLA_VXLAN_LOCAL:
- vxlan.SrcAddr = net.IP(datum.Value[0:4])
- case nl.IFLA_VXLAN_LOCAL6:
- vxlan.SrcAddr = net.IP(datum.Value[0:16])
- case nl.IFLA_VXLAN_GROUP:
- vxlan.Group = net.IP(datum.Value[0:4])
- case nl.IFLA_VXLAN_GROUP6:
- vxlan.Group = net.IP(datum.Value[0:16])
- case nl.IFLA_VXLAN_TTL:
- vxlan.TTL = int(datum.Value[0])
- case nl.IFLA_VXLAN_TOS:
- vxlan.TOS = int(datum.Value[0])
- case nl.IFLA_VXLAN_LEARNING:
- vxlan.Learning = int8(datum.Value[0]) != 0
- case nl.IFLA_VXLAN_PROXY:
- vxlan.Proxy = int8(datum.Value[0]) != 0
- case nl.IFLA_VXLAN_RSC:
- vxlan.RSC = int8(datum.Value[0]) != 0
- case nl.IFLA_VXLAN_L2MISS:
- vxlan.L2miss = int8(datum.Value[0]) != 0
- case nl.IFLA_VXLAN_L3MISS:
- vxlan.L3miss = int8(datum.Value[0]) != 0
- case nl.IFLA_VXLAN_GBP:
- vxlan.GBP = int8(datum.Value[0]) != 0
- case nl.IFLA_VXLAN_AGEING:
- vxlan.Age = int(native.Uint32(datum.Value[0:4]))
- vxlan.NoAge = vxlan.Age == 0
- case nl.IFLA_VXLAN_LIMIT:
- vxlan.Limit = int(native.Uint32(datum.Value[0:4]))
- case nl.IFLA_VXLAN_PORT:
- vxlan.Port = int(native.Uint16(datum.Value[0:2]))
- case nl.IFLA_VXLAN_PORT_RANGE:
- buf := bytes.NewBuffer(datum.Value[0:4])
- var pr vxlanPortRange
- if binary.Read(buf, binary.BigEndian, &pr) != nil {
- vxlan.PortLow = int(pr.Lo)
- vxlan.PortHigh = int(pr.Hi)
- }
- }
- }
-}
-
-func parseIPVlanData(link Link, data []syscall.NetlinkRouteAttr) {
- ipv := link.(*IPVlan)
- for _, datum := range data {
- if datum.Attr.Type == nl.IFLA_IPVLAN_MODE {
- ipv.Mode = IPVlanMode(native.Uint32(datum.Value[0:4]))
- return
- }
- }
-}
-
-func parseMacvtapData(link Link, data []syscall.NetlinkRouteAttr) {
- macv := link.(*Macvtap)
- parseMacvlanData(&macv.Macvlan, data)
-}
-
-func parseMacvlanData(link Link, data []syscall.NetlinkRouteAttr) {
- macv := link.(*Macvlan)
- for _, datum := range data {
- if datum.Attr.Type == nl.IFLA_MACVLAN_MODE {
- switch native.Uint32(datum.Value[0:4]) {
- case nl.MACVLAN_MODE_PRIVATE:
- macv.Mode = MACVLAN_MODE_PRIVATE
- case nl.MACVLAN_MODE_VEPA:
- macv.Mode = MACVLAN_MODE_VEPA
- case nl.MACVLAN_MODE_BRIDGE:
- macv.Mode = MACVLAN_MODE_BRIDGE
- case nl.MACVLAN_MODE_PASSTHRU:
- macv.Mode = MACVLAN_MODE_PASSTHRU
- case nl.MACVLAN_MODE_SOURCE:
- macv.Mode = MACVLAN_MODE_SOURCE
- }
- return
- }
- }
-}
-
-// copied from pkg/net_linux.go
-func linkFlags(rawFlags uint32) net.Flags {
- var f net.Flags
- if rawFlags&syscall.IFF_UP != 0 {
- f |= net.FlagUp
- }
- if rawFlags&syscall.IFF_BROADCAST != 0 {
- f |= net.FlagBroadcast
- }
- if rawFlags&syscall.IFF_LOOPBACK != 0 {
- f |= net.FlagLoopback
- }
- if rawFlags&syscall.IFF_POINTOPOINT != 0 {
- f |= net.FlagPointToPoint
- }
- if rawFlags&syscall.IFF_MULTICAST != 0 {
- f |= net.FlagMulticast
- }
- return f
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/neigh.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/neigh.go
deleted file mode 100644
index 0e5eb90c..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/neigh.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package netlink
-
-import (
- "fmt"
- "net"
-)
-
-// Neigh represents a link layer neighbor from netlink.
-type Neigh struct {
- LinkIndex int
- Family int
- State int
- Type int
- Flags int
- IP net.IP
- HardwareAddr net.HardwareAddr
-}
-
-// String returns $ip/$hwaddr $label
-func (neigh *Neigh) String() string {
- return fmt.Sprintf("%s %s", neigh.IP, neigh.HardwareAddr)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/neigh_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/neigh_linux.go
deleted file mode 100644
index 620a0ee7..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/neigh_linux.go
+++ /dev/null
@@ -1,189 +0,0 @@
-package netlink
-
-import (
- "net"
- "syscall"
- "unsafe"
-
- "github.com/vishvananda/netlink/nl"
-)
-
-const (
- NDA_UNSPEC = iota
- NDA_DST
- NDA_LLADDR
- NDA_CACHEINFO
- NDA_PROBES
- NDA_VLAN
- NDA_PORT
- NDA_VNI
- NDA_IFINDEX
- NDA_MAX = NDA_IFINDEX
-)
-
-// Neighbor Cache Entry States.
-const (
- NUD_NONE = 0x00
- NUD_INCOMPLETE = 0x01
- NUD_REACHABLE = 0x02
- NUD_STALE = 0x04
- NUD_DELAY = 0x08
- NUD_PROBE = 0x10
- NUD_FAILED = 0x20
- NUD_NOARP = 0x40
- NUD_PERMANENT = 0x80
-)
-
-// Neighbor Flags
-const (
- NTF_USE = 0x01
- NTF_SELF = 0x02
- NTF_MASTER = 0x04
- NTF_PROXY = 0x08
- NTF_ROUTER = 0x80
-)
-
-type Ndmsg struct {
- Family uint8
- Index uint32
- State uint16
- Flags uint8
- Type uint8
-}
-
-func deserializeNdmsg(b []byte) *Ndmsg {
- var dummy Ndmsg
- return (*Ndmsg)(unsafe.Pointer(&b[0:unsafe.Sizeof(dummy)][0]))
-}
-
-func (msg *Ndmsg) Serialize() []byte {
- return (*(*[unsafe.Sizeof(*msg)]byte)(unsafe.Pointer(msg)))[:]
-}
-
-func (msg *Ndmsg) Len() int {
- return int(unsafe.Sizeof(*msg))
-}
-
-// NeighAdd will add an IP to MAC mapping to the ARP table
-// Equivalent to: `ip neigh add ....`
-func NeighAdd(neigh *Neigh) error {
- return neighAdd(neigh, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL)
-}
-
-// NeighAdd will add or replace an IP to MAC mapping to the ARP table
-// Equivalent to: `ip neigh replace....`
-func NeighSet(neigh *Neigh) error {
- return neighAdd(neigh, syscall.NLM_F_CREATE)
-}
-
-// NeighAppend will append an entry to FDB
-// Equivalent to: `bridge fdb append...`
-func NeighAppend(neigh *Neigh) error {
- return neighAdd(neigh, syscall.NLM_F_CREATE|syscall.NLM_F_APPEND)
-}
-
-func neighAdd(neigh *Neigh, mode int) error {
- req := nl.NewNetlinkRequest(syscall.RTM_NEWNEIGH, mode|syscall.NLM_F_ACK)
- return neighHandle(neigh, req)
-}
-
-// NeighDel will delete an IP address from a link device.
-// Equivalent to: `ip addr del $addr dev $link`
-func NeighDel(neigh *Neigh) error {
- req := nl.NewNetlinkRequest(syscall.RTM_DELNEIGH, syscall.NLM_F_ACK)
- return neighHandle(neigh, req)
-}
-
-func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
- var family int
- if neigh.Family > 0 {
- family = neigh.Family
- } else {
- family = nl.GetIPFamily(neigh.IP)
- }
-
- msg := Ndmsg{
- Family: uint8(family),
- Index: uint32(neigh.LinkIndex),
- State: uint16(neigh.State),
- Type: uint8(neigh.Type),
- Flags: uint8(neigh.Flags),
- }
- req.AddData(&msg)
-
- ipData := neigh.IP.To4()
- if ipData == nil {
- ipData = neigh.IP.To16()
- }
-
- dstData := nl.NewRtAttr(NDA_DST, ipData)
- req.AddData(dstData)
-
- hwData := nl.NewRtAttr(NDA_LLADDR, []byte(neigh.HardwareAddr))
- req.AddData(hwData)
-
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- return err
-}
-
-// NeighList gets a list of IP-MAC mappings in the system (ARP table).
-// Equivalent to: `ip neighbor show`.
-// The list can be filtered by link and ip family.
-func NeighList(linkIndex, family int) ([]Neigh, error) {
- req := nl.NewNetlinkRequest(syscall.RTM_GETNEIGH, syscall.NLM_F_DUMP)
- msg := Ndmsg{
- Family: uint8(family),
- }
- req.AddData(&msg)
-
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWNEIGH)
- if err != nil {
- return nil, err
- }
-
- var res []Neigh
- for _, m := range msgs {
- ndm := deserializeNdmsg(m)
- if linkIndex != 0 && int(ndm.Index) != linkIndex {
- // Ignore messages from other interfaces
- continue
- }
-
- neigh, err := NeighDeserialize(m)
- if err != nil {
- continue
- }
-
- res = append(res, *neigh)
- }
-
- return res, nil
-}
-
-func NeighDeserialize(m []byte) (*Neigh, error) {
- msg := deserializeNdmsg(m)
-
- neigh := Neigh{
- LinkIndex: int(msg.Index),
- Family: int(msg.Family),
- State: int(msg.State),
- Type: int(msg.Type),
- Flags: int(msg.Flags),
- }
-
- attrs, err := nl.ParseRouteAttr(m[msg.Len():])
- if err != nil {
- return nil, err
- }
-
- for _, attr := range attrs {
- switch attr.Attr.Type {
- case NDA_DST:
- neigh.IP = net.IP(attr.Value)
- case NDA_LLADDR:
- neigh.HardwareAddr = net.HardwareAddr(attr.Value)
- }
- }
-
- return &neigh, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/netlink.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/netlink.go
deleted file mode 100644
index 41ebdb11..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/netlink.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// Package netlink provides a simple library for netlink. Netlink is
-// the interface a user-space program in linux uses to communicate with
-// the kernel. It can be used to add and remove interfaces, set up ip
-// addresses and routes, and confiugre ipsec. Netlink communication
-// requires elevated privileges, so in most cases this code needs to
-// be run as root. The low level primitives for netlink are contained
-// in the nl subpackage. This package attempts to provide a high-level
-// interface that is loosly modeled on the iproute2 cli.
-package netlink
-
-import (
- "net"
-
- "github.com/vishvananda/netlink/nl"
-)
-
-const (
- // Family type definitions
- FAMILY_ALL = nl.FAMILY_ALL
- FAMILY_V4 = nl.FAMILY_V4
- FAMILY_V6 = nl.FAMILY_V6
-)
-
-// ParseIPNet parses a string in ip/net format and returns a net.IPNet.
-// This is valuable because addresses in netlink are often IPNets and
-// ParseCIDR returns an IPNet with the IP part set to the base IP of the
-// range.
-func ParseIPNet(s string) (*net.IPNet, error) {
- ip, ipNet, err := net.ParseCIDR(s)
- if err != nil {
- return nil, err
- }
- return &net.IPNet{IP: ip, Mask: ipNet.Mask}, nil
-}
-
-// NewIPNet generates an IPNet from an ip address using a netmask of 32.
-func NewIPNet(ip net.IP) *net.IPNet {
- return &net.IPNet{IP: ip, Mask: net.CIDRMask(32, 32)}
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/netlink_unspecified.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/netlink_unspecified.go
deleted file mode 100644
index 10c49c1b..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/netlink_unspecified.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// +build !linux
-
-package netlink
-
-import (
- "errors"
-)
-
-var (
- ErrNotImplemented = errors.New("not implemented")
-)
-
-func LinkSetUp(link *Link) error {
- return ErrNotImplemented
-}
-
-func LinkSetDown(link *Link) error {
- return ErrNotImplemented
-}
-
-func LinkSetMTU(link *Link, mtu int) error {
- return ErrNotImplemented
-}
-
-func LinkSetMaster(link *Link, master *Link) error {
- return ErrNotImplemented
-}
-
-func LinkSetNsPid(link *Link, nspid int) error {
- return ErrNotImplemented
-}
-
-func LinkSetNsFd(link *Link, fd int) error {
- return ErrNotImplemented
-}
-
-func LinkAdd(link *Link) error {
- return ErrNotImplemented
-}
-
-func LinkDel(link *Link) error {
- return ErrNotImplemented
-}
-
-func SetHairpin(link Link, mode bool) error {
- return ErrNotImplemented
-}
-
-func SetGuard(link Link, mode bool) error {
- return ErrNotImplemented
-}
-
-func SetFastLeave(link Link, mode bool) error {
- return ErrNotImplemented
-}
-
-func SetLearning(link Link, mode bool) error {
- return ErrNotImplemented
-}
-
-func SetRootBlock(link Link, mode bool) error {
- return ErrNotImplemented
-}
-
-func SetFlood(link Link, mode bool) error {
- return ErrNotImplemented
-}
-
-func LinkList() ([]Link, error) {
- return nil, ErrNotImplemented
-}
-
-func AddrAdd(link *Link, addr *Addr) error {
- return ErrNotImplemented
-}
-
-func AddrDel(link *Link, addr *Addr) error {
- return ErrNotImplemented
-}
-
-func AddrList(link *Link, family int) ([]Addr, error) {
- return nil, ErrNotImplemented
-}
-
-func RouteAdd(route *Route) error {
- return ErrNotImplemented
-}
-
-func RouteDel(route *Route) error {
- return ErrNotImplemented
-}
-
-func RouteList(link *Link, family int) ([]Route, error) {
- return nil, ErrNotImplemented
-}
-
-func XfrmPolicyAdd(policy *XfrmPolicy) error {
- return ErrNotImplemented
-}
-
-func XfrmPolicyDel(policy *XfrmPolicy) error {
- return ErrNotImplemented
-}
-
-func XfrmPolicyList(family int) ([]XfrmPolicy, error) {
- return nil, ErrNotImplemented
-}
-
-func XfrmStateAdd(policy *XfrmState) error {
- return ErrNotImplemented
-}
-
-func XfrmStateDel(policy *XfrmState) error {
- return ErrNotImplemented
-}
-
-func XfrmStateList(family int) ([]XfrmState, error) {
- return nil, ErrNotImplemented
-}
-
-func NeighAdd(neigh *Neigh) error {
- return ErrNotImplemented
-}
-
-func NeighSet(neigh *Neigh) error {
- return ErrNotImplemented
-}
-
-func NeighAppend(neigh *Neigh) error {
- return ErrNotImplemented
-}
-
-func NeighDel(neigh *Neigh) error {
- return ErrNotImplemented
-}
-
-func NeighList(linkIndex, family int) ([]Neigh, error) {
- return nil, ErrNotImplemented
-}
-
-func NeighDeserialize(m []byte) (*Ndmsg, *Neigh, error) {
- return nil, nil, ErrNotImplemented
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/addr_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/addr_linux.go
deleted file mode 100644
index 17088fa0..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/addr_linux.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package nl
-
-import (
- "syscall"
- "unsafe"
-)
-
-type IfAddrmsg struct {
- syscall.IfAddrmsg
-}
-
-func NewIfAddrmsg(family int) *IfAddrmsg {
- return &IfAddrmsg{
- IfAddrmsg: syscall.IfAddrmsg{
- Family: uint8(family),
- },
- }
-}
-
-// struct ifaddrmsg {
-// __u8 ifa_family;
-// __u8 ifa_prefixlen; /* The prefix length */
-// __u8 ifa_flags; /* Flags */
-// __u8 ifa_scope; /* Address scope */
-// __u32 ifa_index; /* Link index */
-// };
-
-// type IfAddrmsg struct {
-// Family uint8
-// Prefixlen uint8
-// Flags uint8
-// Scope uint8
-// Index uint32
-// }
-// SizeofIfAddrmsg = 0x8
-
-func DeserializeIfAddrmsg(b []byte) *IfAddrmsg {
- return (*IfAddrmsg)(unsafe.Pointer(&b[0:syscall.SizeofIfAddrmsg][0]))
-}
-
-func (msg *IfAddrmsg) Serialize() []byte {
- return (*(*[syscall.SizeofIfAddrmsg]byte)(unsafe.Pointer(msg)))[:]
-}
-
-func (msg *IfAddrmsg) Len() int {
- return syscall.SizeofIfAddrmsg
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/link_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/link_linux.go
deleted file mode 100644
index 1f9ab088..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/link_linux.go
+++ /dev/null
@@ -1,104 +0,0 @@
-package nl
-
-const (
- DEFAULT_CHANGE = 0xFFFFFFFF
-)
-
-const (
- IFLA_INFO_UNSPEC = iota
- IFLA_INFO_KIND
- IFLA_INFO_DATA
- IFLA_INFO_XSTATS
- IFLA_INFO_MAX = IFLA_INFO_XSTATS
-)
-
-const (
- IFLA_VLAN_UNSPEC = iota
- IFLA_VLAN_ID
- IFLA_VLAN_FLAGS
- IFLA_VLAN_EGRESS_QOS
- IFLA_VLAN_INGRESS_QOS
- IFLA_VLAN_PROTOCOL
- IFLA_VLAN_MAX = IFLA_VLAN_PROTOCOL
-)
-
-const (
- VETH_INFO_UNSPEC = iota
- VETH_INFO_PEER
- VETH_INFO_MAX = VETH_INFO_PEER
-)
-
-const (
- IFLA_VXLAN_UNSPEC = iota
- IFLA_VXLAN_ID
- IFLA_VXLAN_GROUP
- IFLA_VXLAN_LINK
- IFLA_VXLAN_LOCAL
- IFLA_VXLAN_TTL
- IFLA_VXLAN_TOS
- IFLA_VXLAN_LEARNING
- IFLA_VXLAN_AGEING
- IFLA_VXLAN_LIMIT
- IFLA_VXLAN_PORT_RANGE
- IFLA_VXLAN_PROXY
- IFLA_VXLAN_RSC
- IFLA_VXLAN_L2MISS
- IFLA_VXLAN_L3MISS
- IFLA_VXLAN_PORT
- IFLA_VXLAN_GROUP6
- IFLA_VXLAN_LOCAL6
- IFLA_VXLAN_UDP_CSUM
- IFLA_VXLAN_UDP_ZERO_CSUM6_TX
- IFLA_VXLAN_UDP_ZERO_CSUM6_RX
- IFLA_VXLAN_REMCSUM_TX
- IFLA_VXLAN_REMCSUM_RX
- IFLA_VXLAN_GBP
- IFLA_VXLAN_REMCSUM_NOPARTIAL
- IFLA_VXLAN_FLOWBASED
- IFLA_VXLAN_MAX = IFLA_VXLAN_FLOWBASED
-)
-
-const (
- BRIDGE_MODE_UNSPEC = iota
- BRIDGE_MODE_HAIRPIN
-)
-
-const (
- IFLA_BRPORT_UNSPEC = iota
- IFLA_BRPORT_STATE
- IFLA_BRPORT_PRIORITY
- IFLA_BRPORT_COST
- IFLA_BRPORT_MODE
- IFLA_BRPORT_GUARD
- IFLA_BRPORT_PROTECT
- IFLA_BRPORT_FAST_LEAVE
- IFLA_BRPORT_LEARNING
- IFLA_BRPORT_UNICAST_FLOOD
- IFLA_BRPORT_MAX = IFLA_BRPORT_UNICAST_FLOOD
-)
-
-const (
- IFLA_IPVLAN_UNSPEC = iota
- IFLA_IPVLAN_MODE
- IFLA_IPVLAN_MAX = IFLA_IPVLAN_MODE
-)
-
-const (
- // not defined in syscall
- IFLA_NET_NS_FD = 28
-)
-
-const (
- IFLA_MACVLAN_UNSPEC = iota
- IFLA_MACVLAN_MODE
- IFLA_MACVLAN_FLAGS
- IFLA_MACVLAN_MAX = IFLA_MACVLAN_FLAGS
-)
-
-const (
- MACVLAN_MODE_PRIVATE = 1
- MACVLAN_MODE_VEPA = 2
- MACVLAN_MODE_BRIDGE = 4
- MACVLAN_MODE_PASSTHRU = 8
- MACVLAN_MODE_SOURCE = 16
-)
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/nl_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/nl_linux.go
deleted file mode 100644
index 8dbd92b8..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/nl_linux.go
+++ /dev/null
@@ -1,418 +0,0 @@
-// Package nl has low level primitives for making Netlink calls.
-package nl
-
-import (
- "bytes"
- "encoding/binary"
- "fmt"
- "net"
- "sync/atomic"
- "syscall"
- "unsafe"
-)
-
-const (
- // Family type definitions
- FAMILY_ALL = syscall.AF_UNSPEC
- FAMILY_V4 = syscall.AF_INET
- FAMILY_V6 = syscall.AF_INET6
-)
-
-var nextSeqNr uint32
-
-// GetIPFamily returns the family type of a net.IP.
-func GetIPFamily(ip net.IP) int {
- if len(ip) <= net.IPv4len {
- return FAMILY_V4
- }
- if ip.To4() != nil {
- return FAMILY_V4
- }
- return FAMILY_V6
-}
-
-var nativeEndian binary.ByteOrder
-
-// Get native endianness for the system
-func NativeEndian() binary.ByteOrder {
- if nativeEndian == nil {
- var x uint32 = 0x01020304
- if *(*byte)(unsafe.Pointer(&x)) == 0x01 {
- nativeEndian = binary.BigEndian
- } else {
- nativeEndian = binary.LittleEndian
- }
- }
- return nativeEndian
-}
-
-// Byte swap a 16 bit value if we aren't big endian
-func Swap16(i uint16) uint16 {
- if NativeEndian() == binary.BigEndian {
- return i
- }
- return (i&0xff00)>>8 | (i&0xff)<<8
-}
-
-// Byte swap a 32 bit value if aren't big endian
-func Swap32(i uint32) uint32 {
- if NativeEndian() == binary.BigEndian {
- return i
- }
- return (i&0xff000000)>>24 | (i&0xff0000)>>8 | (i&0xff00)<<8 | (i&0xff)<<24
-}
-
-type NetlinkRequestData interface {
- Len() int
- Serialize() []byte
-}
-
-// IfInfomsg is related to links, but it is used for list requests as well
-type IfInfomsg struct {
- syscall.IfInfomsg
-}
-
-// Create an IfInfomsg with family specified
-func NewIfInfomsg(family int) *IfInfomsg {
- return &IfInfomsg{
- IfInfomsg: syscall.IfInfomsg{
- Family: uint8(family),
- },
- }
-}
-
-func DeserializeIfInfomsg(b []byte) *IfInfomsg {
- return (*IfInfomsg)(unsafe.Pointer(&b[0:syscall.SizeofIfInfomsg][0]))
-}
-
-func (msg *IfInfomsg) Serialize() []byte {
- return (*(*[syscall.SizeofIfInfomsg]byte)(unsafe.Pointer(msg)))[:]
-}
-
-func (msg *IfInfomsg) Len() int {
- return syscall.SizeofIfInfomsg
-}
-
-func rtaAlignOf(attrlen int) int {
- return (attrlen + syscall.RTA_ALIGNTO - 1) & ^(syscall.RTA_ALIGNTO - 1)
-}
-
-func NewIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg {
- msg := NewIfInfomsg(family)
- parent.children = append(parent.children, msg)
- return msg
-}
-
-// Extend RtAttr to handle data and children
-type RtAttr struct {
- syscall.RtAttr
- Data []byte
- children []NetlinkRequestData
-}
-
-// Create a new Extended RtAttr object
-func NewRtAttr(attrType int, data []byte) *RtAttr {
- return &RtAttr{
- RtAttr: syscall.RtAttr{
- Type: uint16(attrType),
- },
- children: []NetlinkRequestData{},
- Data: data,
- }
-}
-
-// Create a new RtAttr obj anc add it as a child of an existing object
-func NewRtAttrChild(parent *RtAttr, attrType int, data []byte) *RtAttr {
- attr := NewRtAttr(attrType, data)
- parent.children = append(parent.children, attr)
- return attr
-}
-
-func (a *RtAttr) Len() int {
- if len(a.children) == 0 {
- return (syscall.SizeofRtAttr + len(a.Data))
- }
-
- l := 0
- for _, child := range a.children {
- l += rtaAlignOf(child.Len())
- }
- l += syscall.SizeofRtAttr
- return rtaAlignOf(l + len(a.Data))
-}
-
-// Serialize the RtAttr into a byte array
-// This can't just unsafe.cast because it must iterate through children.
-func (a *RtAttr) Serialize() []byte {
- native := NativeEndian()
-
- length := a.Len()
- buf := make([]byte, rtaAlignOf(length))
-
- if a.Data != nil {
- copy(buf[4:], a.Data)
- } else {
- next := 4
- for _, child := range a.children {
- childBuf := child.Serialize()
- copy(buf[next:], childBuf)
- next += rtaAlignOf(len(childBuf))
- }
- }
-
- if l := uint16(length); l != 0 {
- native.PutUint16(buf[0:2], l)
- }
- native.PutUint16(buf[2:4], a.Type)
- return buf
-}
-
-type NetlinkRequest struct {
- syscall.NlMsghdr
- Data []NetlinkRequestData
-}
-
-// Serialize the Netlink Request into a byte array
-func (req *NetlinkRequest) Serialize() []byte {
- length := syscall.SizeofNlMsghdr
- dataBytes := make([][]byte, len(req.Data))
- for i, data := range req.Data {
- dataBytes[i] = data.Serialize()
- length = length + len(dataBytes[i])
- }
- req.Len = uint32(length)
- b := make([]byte, length)
- hdr := (*(*[syscall.SizeofNlMsghdr]byte)(unsafe.Pointer(req)))[:]
- next := syscall.SizeofNlMsghdr
- copy(b[0:next], hdr)
- for _, data := range dataBytes {
- for _, dataByte := range data {
- b[next] = dataByte
- next = next + 1
- }
- }
- return b
-}
-
-func (req *NetlinkRequest) AddData(data NetlinkRequestData) {
- if data != nil {
- req.Data = append(req.Data, data)
- }
-}
-
-// Execute the request against a the given sockType.
-// Returns a list of netlink messages in seriaized format, optionally filtered
-// by resType.
-func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, error) {
- s, err := getNetlinkSocket(sockType)
- if err != nil {
- return nil, err
- }
- defer s.Close()
-
- if err := s.Send(req); err != nil {
- return nil, err
- }
-
- pid, err := s.GetPid()
- if err != nil {
- return nil, err
- }
-
- var res [][]byte
-
-done:
- for {
- msgs, err := s.Receive()
- if err != nil {
- return nil, err
- }
- for _, m := range msgs {
- if m.Header.Seq != req.Seq {
- return nil, fmt.Errorf("Wrong Seq nr %d, expected 1", m.Header.Seq)
- }
- if m.Header.Pid != pid {
- return nil, fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, pid)
- }
- if m.Header.Type == syscall.NLMSG_DONE {
- break done
- }
- if m.Header.Type == syscall.NLMSG_ERROR {
- native := NativeEndian()
- error := int32(native.Uint32(m.Data[0:4]))
- if error == 0 {
- break done
- }
- return nil, syscall.Errno(-error)
- }
- if resType != 0 && m.Header.Type != resType {
- continue
- }
- res = append(res, m.Data)
- if m.Header.Flags&syscall.NLM_F_MULTI == 0 {
- break done
- }
- }
- }
- return res, nil
-}
-
-// Create a new netlink request from proto and flags
-// Note the Len value will be inaccurate once data is added until
-// the message is serialized
-func NewNetlinkRequest(proto, flags int) *NetlinkRequest {
- return &NetlinkRequest{
- NlMsghdr: syscall.NlMsghdr{
- Len: uint32(syscall.SizeofNlMsghdr),
- Type: uint16(proto),
- Flags: syscall.NLM_F_REQUEST | uint16(flags),
- Seq: atomic.AddUint32(&nextSeqNr, 1),
- },
- }
-}
-
-type NetlinkSocket struct {
- fd int
- lsa syscall.SockaddrNetlink
-}
-
-func getNetlinkSocket(protocol int) (*NetlinkSocket, error) {
- fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, protocol)
- if err != nil {
- return nil, err
- }
- s := &NetlinkSocket{
- fd: fd,
- }
- s.lsa.Family = syscall.AF_NETLINK
- if err := syscall.Bind(fd, &s.lsa); err != nil {
- syscall.Close(fd)
- return nil, err
- }
-
- return s, nil
-}
-
-// Create a netlink socket with a given protocol (e.g. NETLINK_ROUTE)
-// and subscribe it to multicast groups passed in variable argument list.
-// Returns the netlink socket on which Receive() method can be called
-// to retrieve the messages from the kernel.
-func Subscribe(protocol int, groups ...uint) (*NetlinkSocket, error) {
- fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, protocol)
- if err != nil {
- return nil, err
- }
- s := &NetlinkSocket{
- fd: fd,
- }
- s.lsa.Family = syscall.AF_NETLINK
-
- for _, g := range groups {
- s.lsa.Groups |= (1 << (g - 1))
- }
-
- if err := syscall.Bind(fd, &s.lsa); err != nil {
- syscall.Close(fd)
- return nil, err
- }
-
- return s, nil
-}
-
-func (s *NetlinkSocket) Close() {
- syscall.Close(s.fd)
-}
-
-func (s *NetlinkSocket) Send(request *NetlinkRequest) error {
- if err := syscall.Sendto(s.fd, request.Serialize(), 0, &s.lsa); err != nil {
- return err
- }
- return nil
-}
-
-func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) {
- rb := make([]byte, syscall.Getpagesize())
- nr, _, err := syscall.Recvfrom(s.fd, rb, 0)
- if err != nil {
- return nil, err
- }
- if nr < syscall.NLMSG_HDRLEN {
- return nil, fmt.Errorf("Got short response from netlink")
- }
- rb = rb[:nr]
- return syscall.ParseNetlinkMessage(rb)
-}
-
-func (s *NetlinkSocket) GetPid() (uint32, error) {
- lsa, err := syscall.Getsockname(s.fd)
- if err != nil {
- return 0, err
- }
- switch v := lsa.(type) {
- case *syscall.SockaddrNetlink:
- return v.Pid, nil
- }
- return 0, fmt.Errorf("Wrong socket type")
-}
-
-func ZeroTerminated(s string) []byte {
- bytes := make([]byte, len(s)+1)
- for i := 0; i < len(s); i++ {
- bytes[i] = s[i]
- }
- bytes[len(s)] = 0
- return bytes
-}
-
-func NonZeroTerminated(s string) []byte {
- bytes := make([]byte, len(s))
- for i := 0; i < len(s); i++ {
- bytes[i] = s[i]
- }
- return bytes
-}
-
-func BytesToString(b []byte) string {
- n := bytes.Index(b, []byte{0})
- return string(b[:n])
-}
-
-func Uint8Attr(v uint8) []byte {
- return []byte{byte(v)}
-}
-
-func Uint16Attr(v uint16) []byte {
- native := NativeEndian()
- bytes := make([]byte, 2)
- native.PutUint16(bytes, v)
- return bytes
-}
-
-func Uint32Attr(v uint32) []byte {
- native := NativeEndian()
- bytes := make([]byte, 4)
- native.PutUint32(bytes, v)
- return bytes
-}
-
-func ParseRouteAttr(b []byte) ([]syscall.NetlinkRouteAttr, error) {
- var attrs []syscall.NetlinkRouteAttr
- for len(b) >= syscall.SizeofRtAttr {
- a, vbuf, alen, err := netlinkRouteAttrAndValue(b)
- if err != nil {
- return nil, err
- }
- ra := syscall.NetlinkRouteAttr{Attr: *a, Value: vbuf[:int(a.Len)-syscall.SizeofRtAttr]}
- attrs = append(attrs, ra)
- b = b[alen:]
- }
- return attrs, nil
-}
-
-func netlinkRouteAttrAndValue(b []byte) (*syscall.RtAttr, []byte, int, error) {
- a := (*syscall.RtAttr)(unsafe.Pointer(&b[0]))
- if int(a.Len) < syscall.SizeofRtAttr || int(a.Len) > len(b) {
- return nil, nil, 0, syscall.EINVAL
- }
- return a, b[syscall.SizeofRtAttr:], rtaAlignOf(int(a.Len)), nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/route_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/route_linux.go
deleted file mode 100644
index 447e83e5..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/route_linux.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package nl
-
-import (
- "syscall"
- "unsafe"
-)
-
-type RtMsg struct {
- syscall.RtMsg
-}
-
-func NewRtMsg() *RtMsg {
- return &RtMsg{
- RtMsg: syscall.RtMsg{
- Table: syscall.RT_TABLE_MAIN,
- Scope: syscall.RT_SCOPE_UNIVERSE,
- Protocol: syscall.RTPROT_BOOT,
- Type: syscall.RTN_UNICAST,
- },
- }
-}
-
-func NewRtDelMsg() *RtMsg {
- return &RtMsg{
- RtMsg: syscall.RtMsg{
- Table: syscall.RT_TABLE_MAIN,
- Scope: syscall.RT_SCOPE_NOWHERE,
- },
- }
-}
-
-func (msg *RtMsg) Len() int {
- return syscall.SizeofRtMsg
-}
-
-func DeserializeRtMsg(b []byte) *RtMsg {
- return (*RtMsg)(unsafe.Pointer(&b[0:syscall.SizeofRtMsg][0]))
-}
-
-func (msg *RtMsg) Serialize() []byte {
- return (*(*[syscall.SizeofRtMsg]byte)(unsafe.Pointer(msg)))[:]
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/tc_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/tc_linux.go
deleted file mode 100644
index c9bfe8df..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/tc_linux.go
+++ /dev/null
@@ -1,359 +0,0 @@
-package nl
-
-import (
- "unsafe"
-)
-
-// Message types
-const (
- TCA_UNSPEC = iota
- TCA_KIND
- TCA_OPTIONS
- TCA_STATS
- TCA_XSTATS
- TCA_RATE
- TCA_FCNT
- TCA_STATS2
- TCA_STAB
- TCA_MAX = TCA_STAB
-)
-
-const (
- TCA_ACT_TAB = 1
- TCAA_MAX = 1
-)
-
-const (
- TCA_PRIO_UNSPEC = iota
- TCA_PRIO_MQ
- TCA_PRIO_MAX = TCA_PRIO_MQ
-)
-
-const (
- SizeofTcMsg = 0x14
- SizeofTcActionMsg = 0x04
- SizeofTcPrioMap = 0x14
- SizeofTcRateSpec = 0x0c
- SizeofTcTbfQopt = 2*SizeofTcRateSpec + 0x0c
- SizeofTcU32Key = 0x10
- SizeofTcU32Sel = 0x10 // without keys
- SizeofTcMirred = 0x1c
-)
-
-// struct tcmsg {
-// unsigned char tcm_family;
-// unsigned char tcm__pad1;
-// unsigned short tcm__pad2;
-// int tcm_ifindex;
-// __u32 tcm_handle;
-// __u32 tcm_parent;
-// __u32 tcm_info;
-// };
-
-type TcMsg struct {
- Family uint8
- Pad [3]byte
- Ifindex int32
- Handle uint32
- Parent uint32
- Info uint32
-}
-
-func (msg *TcMsg) Len() int {
- return SizeofTcMsg
-}
-
-func DeserializeTcMsg(b []byte) *TcMsg {
- return (*TcMsg)(unsafe.Pointer(&b[0:SizeofTcMsg][0]))
-}
-
-func (x *TcMsg) Serialize() []byte {
- return (*(*[SizeofTcMsg]byte)(unsafe.Pointer(x)))[:]
-}
-
-// struct tcamsg {
-// unsigned char tca_family;
-// unsigned char tca__pad1;
-// unsigned short tca__pad2;
-// };
-
-type TcActionMsg struct {
- Family uint8
- Pad [3]byte
-}
-
-func (msg *TcActionMsg) Len() int {
- return SizeofTcActionMsg
-}
-
-func DeserializeTcActionMsg(b []byte) *TcActionMsg {
- return (*TcActionMsg)(unsafe.Pointer(&b[0:SizeofTcActionMsg][0]))
-}
-
-func (x *TcActionMsg) Serialize() []byte {
- return (*(*[SizeofTcActionMsg]byte)(unsafe.Pointer(x)))[:]
-}
-
-const (
- TC_PRIO_MAX = 15
-)
-
-// struct tc_prio_qopt {
-// int bands; /* Number of bands */
-// __u8 priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */
-// };
-
-type TcPrioMap struct {
- Bands int32
- Priomap [TC_PRIO_MAX + 1]uint8
-}
-
-func (msg *TcPrioMap) Len() int {
- return SizeofTcPrioMap
-}
-
-func DeserializeTcPrioMap(b []byte) *TcPrioMap {
- return (*TcPrioMap)(unsafe.Pointer(&b[0:SizeofTcPrioMap][0]))
-}
-
-func (x *TcPrioMap) Serialize() []byte {
- return (*(*[SizeofTcPrioMap]byte)(unsafe.Pointer(x)))[:]
-}
-
-const (
- TCA_TBF_UNSPEC = iota
- TCA_TBF_PARMS
- TCA_TBF_RTAB
- TCA_TBF_PTAB
- TCA_TBF_RATE64
- TCA_TBF_PRATE64
- TCA_TBF_BURST
- TCA_TBF_PBURST
- TCA_TBF_MAX = TCA_TBF_PBURST
-)
-
-// struct tc_ratespec {
-// unsigned char cell_log;
-// __u8 linklayer; /* lower 4 bits */
-// unsigned short overhead;
-// short cell_align;
-// unsigned short mpu;
-// __u32 rate;
-// };
-
-type TcRateSpec struct {
- CellLog uint8
- Linklayer uint8
- Overhead uint16
- CellAlign int16
- Mpu uint16
- Rate uint32
-}
-
-func (msg *TcRateSpec) Len() int {
- return SizeofTcRateSpec
-}
-
-func DeserializeTcRateSpec(b []byte) *TcRateSpec {
- return (*TcRateSpec)(unsafe.Pointer(&b[0:SizeofTcRateSpec][0]))
-}
-
-func (x *TcRateSpec) Serialize() []byte {
- return (*(*[SizeofTcRateSpec]byte)(unsafe.Pointer(x)))[:]
-}
-
-// struct tc_tbf_qopt {
-// struct tc_ratespec rate;
-// struct tc_ratespec peakrate;
-// __u32 limit;
-// __u32 buffer;
-// __u32 mtu;
-// };
-
-type TcTbfQopt struct {
- Rate TcRateSpec
- Peakrate TcRateSpec
- Limit uint32
- Buffer uint32
- Mtu uint32
-}
-
-func (msg *TcTbfQopt) Len() int {
- return SizeofTcTbfQopt
-}
-
-func DeserializeTcTbfQopt(b []byte) *TcTbfQopt {
- return (*TcTbfQopt)(unsafe.Pointer(&b[0:SizeofTcTbfQopt][0]))
-}
-
-func (x *TcTbfQopt) Serialize() []byte {
- return (*(*[SizeofTcTbfQopt]byte)(unsafe.Pointer(x)))[:]
-}
-
-const (
- TCA_U32_UNSPEC = iota
- TCA_U32_CLASSID
- TCA_U32_HASH
- TCA_U32_LINK
- TCA_U32_DIVISOR
- TCA_U32_SEL
- TCA_U32_POLICE
- TCA_U32_ACT
- TCA_U32_INDEV
- TCA_U32_PCNT
- TCA_U32_MARK
- TCA_U32_MAX = TCA_U32_MARK
-)
-
-// struct tc_u32_key {
-// __be32 mask;
-// __be32 val;
-// int off;
-// int offmask;
-// };
-
-type TcU32Key struct {
- Mask uint32 // big endian
- Val uint32 // big endian
- Off int32
- OffMask int32
-}
-
-func (msg *TcU32Key) Len() int {
- return SizeofTcU32Key
-}
-
-func DeserializeTcU32Key(b []byte) *TcU32Key {
- return (*TcU32Key)(unsafe.Pointer(&b[0:SizeofTcU32Key][0]))
-}
-
-func (x *TcU32Key) Serialize() []byte {
- return (*(*[SizeofTcU32Key]byte)(unsafe.Pointer(x)))[:]
-}
-
-// struct tc_u32_sel {
-// unsigned char flags;
-// unsigned char offshift;
-// unsigned char nkeys;
-//
-// __be16 offmask;
-// __u16 off;
-// short offoff;
-//
-// short hoff;
-// __be32 hmask;
-// struct tc_u32_key keys[0];
-// };
-
-const (
- TC_U32_TERMINAL = 1 << iota
- TC_U32_OFFSET = 1 << iota
- TC_U32_VAROFFSET = 1 << iota
- TC_U32_EAT = 1 << iota
-)
-
-type TcU32Sel struct {
- Flags uint8
- Offshift uint8
- Nkeys uint8
- Pad uint8
- Offmask uint16 // big endian
- Off uint16
- Offoff int16
- Hoff int16
- Hmask uint32 // big endian
- Keys []TcU32Key
-}
-
-func (msg *TcU32Sel) Len() int {
- return SizeofTcU32Sel + int(msg.Nkeys)*SizeofTcU32Key
-}
-
-func DeserializeTcU32Sel(b []byte) *TcU32Sel {
- x := &TcU32Sel{}
- copy((*(*[SizeofTcU32Sel]byte)(unsafe.Pointer(x)))[:], b)
- next := SizeofTcU32Sel
- var i uint8
- for i = 0; i < x.Nkeys; i++ {
- x.Keys = append(x.Keys, *DeserializeTcU32Key(b[next:]))
- next += SizeofTcU32Key
- }
- return x
-}
-
-func (x *TcU32Sel) Serialize() []byte {
- // This can't just unsafe.cast because it must iterate through keys.
- buf := make([]byte, x.Len())
- copy(buf, (*(*[SizeofTcU32Sel]byte)(unsafe.Pointer(x)))[:])
- next := SizeofTcU32Sel
- for _, key := range x.Keys {
- keyBuf := key.Serialize()
- copy(buf[next:], keyBuf)
- next += SizeofTcU32Key
- }
- return buf
-}
-
-const (
- TCA_ACT_MIRRED = 8
-)
-
-const (
- TCA_MIRRED_UNSPEC = iota
- TCA_MIRRED_TM
- TCA_MIRRED_PARMS
- TCA_MIRRED_MAX = TCA_MIRRED_PARMS
-)
-
-const (
- TCA_EGRESS_REDIR = 1 /* packet redirect to EGRESS*/
- TCA_EGRESS_MIRROR = 2 /* mirror packet to EGRESS */
- TCA_INGRESS_REDIR = 3 /* packet redirect to INGRESS*/
- TCA_INGRESS_MIRROR = 4 /* mirror packet to INGRESS */
-)
-
-const (
- TC_ACT_UNSPEC = int32(-1)
- TC_ACT_OK = 0
- TC_ACT_RECLASSIFY = 1
- TC_ACT_SHOT = 2
- TC_ACT_PIPE = 3
- TC_ACT_STOLEN = 4
- TC_ACT_QUEUED = 5
- TC_ACT_REPEAT = 6
- TC_ACT_JUMP = 0x10000000
-)
-
-// #define tc_gen \
-// __u32 index; \
-// __u32 capab; \
-// int action; \
-// int refcnt; \
-// int bindcnt
-// struct tc_mirred {
-// tc_gen;
-// int eaction; /* one of IN/EGRESS_MIRROR/REDIR */
-// __u32 ifindex; /* ifindex of egress port */
-// };
-
-type TcMirred struct {
- Index uint32
- Capab uint32
- Action int32
- Refcnt int32
- Bindcnt int32
- Eaction int32
- Ifindex uint32
-}
-
-func (msg *TcMirred) Len() int {
- return SizeofTcMirred
-}
-
-func DeserializeTcMirred(b []byte) *TcMirred {
- return (*TcMirred)(unsafe.Pointer(&b[0:SizeofTcMirred][0]))
-}
-
-func (x *TcMirred) Serialize() []byte {
- return (*(*[SizeofTcMirred]byte)(unsafe.Pointer(x)))[:]
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_linux.go
deleted file mode 100644
index d24637d2..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_linux.go
+++ /dev/null
@@ -1,258 +0,0 @@
-package nl
-
-import (
- "bytes"
- "net"
- "unsafe"
-)
-
-// Infinity for packet and byte counts
-const (
- XFRM_INF = ^uint64(0)
-)
-
-// Message Types
-const (
- XFRM_MSG_BASE = 0x10
- XFRM_MSG_NEWSA = 0x10
- XFRM_MSG_DELSA = 0x11
- XFRM_MSG_GETSA = 0x12
- XFRM_MSG_NEWPOLICY = 0x13
- XFRM_MSG_DELPOLICY = 0x14
- XFRM_MSG_GETPOLICY = 0x15
- XFRM_MSG_ALLOCSPI = 0x16
- XFRM_MSG_ACQUIRE = 0x17
- XFRM_MSG_EXPIRE = 0x18
- XFRM_MSG_UPDPOLICY = 0x19
- XFRM_MSG_UPDSA = 0x1a
- XFRM_MSG_POLEXPIRE = 0x1b
- XFRM_MSG_FLUSHSA = 0x1c
- XFRM_MSG_FLUSHPOLICY = 0x1d
- XFRM_MSG_NEWAE = 0x1e
- XFRM_MSG_GETAE = 0x1f
- XFRM_MSG_REPORT = 0x20
- XFRM_MSG_MIGRATE = 0x21
- XFRM_MSG_NEWSADINFO = 0x22
- XFRM_MSG_GETSADINFO = 0x23
- XFRM_MSG_NEWSPDINFO = 0x24
- XFRM_MSG_GETSPDINFO = 0x25
- XFRM_MSG_MAPPING = 0x26
- XFRM_MSG_MAX = 0x26
- XFRM_NR_MSGTYPES = 0x17
-)
-
-// Attribute types
-const (
- /* Netlink message attributes. */
- XFRMA_UNSPEC = 0x00
- XFRMA_ALG_AUTH = 0x01 /* struct xfrm_algo */
- XFRMA_ALG_CRYPT = 0x02 /* struct xfrm_algo */
- XFRMA_ALG_COMP = 0x03 /* struct xfrm_algo */
- XFRMA_ENCAP = 0x04 /* struct xfrm_algo + struct xfrm_encap_tmpl */
- XFRMA_TMPL = 0x05 /* 1 or more struct xfrm_user_tmpl */
- XFRMA_SA = 0x06 /* struct xfrm_usersa_info */
- XFRMA_POLICY = 0x07 /* struct xfrm_userpolicy_info */
- XFRMA_SEC_CTX = 0x08 /* struct xfrm_sec_ctx */
- XFRMA_LTIME_VAL = 0x09
- XFRMA_REPLAY_VAL = 0x0a
- XFRMA_REPLAY_THRESH = 0x0b
- XFRMA_ETIMER_THRESH = 0x0c
- XFRMA_SRCADDR = 0x0d /* xfrm_address_t */
- XFRMA_COADDR = 0x0e /* xfrm_address_t */
- XFRMA_LASTUSED = 0x0f /* unsigned long */
- XFRMA_POLICY_TYPE = 0x10 /* struct xfrm_userpolicy_type */
- XFRMA_MIGRATE = 0x11
- XFRMA_ALG_AEAD = 0x12 /* struct xfrm_algo_aead */
- XFRMA_KMADDRESS = 0x13 /* struct xfrm_user_kmaddress */
- XFRMA_ALG_AUTH_TRUNC = 0x14 /* struct xfrm_algo_auth */
- XFRMA_MARK = 0x15 /* struct xfrm_mark */
- XFRMA_TFCPAD = 0x16 /* __u32 */
- XFRMA_REPLAY_ESN_VAL = 0x17 /* struct xfrm_replay_esn */
- XFRMA_SA_EXTRA_FLAGS = 0x18 /* __u32 */
- XFRMA_MAX = 0x18
-)
-
-const (
- SizeofXfrmAddress = 0x10
- SizeofXfrmSelector = 0x38
- SizeofXfrmLifetimeCfg = 0x40
- SizeofXfrmLifetimeCur = 0x20
- SizeofXfrmId = 0x18
-)
-
-// typedef union {
-// __be32 a4;
-// __be32 a6[4];
-// } xfrm_address_t;
-
-type XfrmAddress [SizeofXfrmAddress]byte
-
-func (x *XfrmAddress) ToIP() net.IP {
- var empty = [12]byte{}
- ip := make(net.IP, net.IPv6len)
- if bytes.Equal(x[4:16], empty[:]) {
- ip[10] = 0xff
- ip[11] = 0xff
- copy(ip[12:16], x[0:4])
- } else {
- copy(ip[:], x[:])
- }
- return ip
-}
-
-func (x *XfrmAddress) ToIPNet(prefixlen uint8) *net.IPNet {
- ip := x.ToIP()
- if GetIPFamily(ip) == FAMILY_V4 {
- return &net.IPNet{IP: ip, Mask: net.CIDRMask(int(prefixlen), 32)}
- }
- return &net.IPNet{IP: ip, Mask: net.CIDRMask(int(prefixlen), 128)}
-}
-
-func (x *XfrmAddress) FromIP(ip net.IP) {
- var empty = [16]byte{}
- if len(ip) < net.IPv4len {
- copy(x[4:16], empty[:])
- } else if GetIPFamily(ip) == FAMILY_V4 {
- copy(x[0:4], ip.To4()[0:4])
- copy(x[4:16], empty[:12])
- } else {
- copy(x[0:16], ip.To16()[0:16])
- }
-}
-
-func DeserializeXfrmAddress(b []byte) *XfrmAddress {
- return (*XfrmAddress)(unsafe.Pointer(&b[0:SizeofXfrmAddress][0]))
-}
-
-func (x *XfrmAddress) Serialize() []byte {
- return (*(*[SizeofXfrmAddress]byte)(unsafe.Pointer(x)))[:]
-}
-
-// struct xfrm_selector {
-// xfrm_address_t daddr;
-// xfrm_address_t saddr;
-// __be16 dport;
-// __be16 dport_mask;
-// __be16 sport;
-// __be16 sport_mask;
-// __u16 family;
-// __u8 prefixlen_d;
-// __u8 prefixlen_s;
-// __u8 proto;
-// int ifindex;
-// __kernel_uid32_t user;
-// };
-
-type XfrmSelector struct {
- Daddr XfrmAddress
- Saddr XfrmAddress
- Dport uint16 // big endian
- DportMask uint16 // big endian
- Sport uint16 // big endian
- SportMask uint16 // big endian
- Family uint16
- PrefixlenD uint8
- PrefixlenS uint8
- Proto uint8
- Pad [3]byte
- Ifindex int32
- User uint32
-}
-
-func (msg *XfrmSelector) Len() int {
- return SizeofXfrmSelector
-}
-
-func DeserializeXfrmSelector(b []byte) *XfrmSelector {
- return (*XfrmSelector)(unsafe.Pointer(&b[0:SizeofXfrmSelector][0]))
-}
-
-func (msg *XfrmSelector) Serialize() []byte {
- return (*(*[SizeofXfrmSelector]byte)(unsafe.Pointer(msg)))[:]
-}
-
-// struct xfrm_lifetime_cfg {
-// __u64 soft_byte_limit;
-// __u64 hard_byte_limit;
-// __u64 soft_packet_limit;
-// __u64 hard_packet_limit;
-// __u64 soft_add_expires_seconds;
-// __u64 hard_add_expires_seconds;
-// __u64 soft_use_expires_seconds;
-// __u64 hard_use_expires_seconds;
-// };
-//
-
-type XfrmLifetimeCfg struct {
- SoftByteLimit uint64
- HardByteLimit uint64
- SoftPacketLimit uint64
- HardPacketLimit uint64
- SoftAddExpiresSeconds uint64
- HardAddExpiresSeconds uint64
- SoftUseExpiresSeconds uint64
- HardUseExpiresSeconds uint64
-}
-
-func (msg *XfrmLifetimeCfg) Len() int {
- return SizeofXfrmLifetimeCfg
-}
-
-func DeserializeXfrmLifetimeCfg(b []byte) *XfrmLifetimeCfg {
- return (*XfrmLifetimeCfg)(unsafe.Pointer(&b[0:SizeofXfrmLifetimeCfg][0]))
-}
-
-func (msg *XfrmLifetimeCfg) Serialize() []byte {
- return (*(*[SizeofXfrmLifetimeCfg]byte)(unsafe.Pointer(msg)))[:]
-}
-
-// struct xfrm_lifetime_cur {
-// __u64 bytes;
-// __u64 packets;
-// __u64 add_time;
-// __u64 use_time;
-// };
-
-type XfrmLifetimeCur struct {
- Bytes uint64
- Packets uint64
- AddTime uint64
- UseTime uint64
-}
-
-func (msg *XfrmLifetimeCur) Len() int {
- return SizeofXfrmLifetimeCur
-}
-
-func DeserializeXfrmLifetimeCur(b []byte) *XfrmLifetimeCur {
- return (*XfrmLifetimeCur)(unsafe.Pointer(&b[0:SizeofXfrmLifetimeCur][0]))
-}
-
-func (msg *XfrmLifetimeCur) Serialize() []byte {
- return (*(*[SizeofXfrmLifetimeCur]byte)(unsafe.Pointer(msg)))[:]
-}
-
-// struct xfrm_id {
-// xfrm_address_t daddr;
-// __be32 spi;
-// __u8 proto;
-// };
-
-type XfrmId struct {
- Daddr XfrmAddress
- Spi uint32 // big endian
- Proto uint8
- Pad [3]byte
-}
-
-func (msg *XfrmId) Len() int {
- return SizeofXfrmId
-}
-
-func DeserializeXfrmId(b []byte) *XfrmId {
- return (*XfrmId)(unsafe.Pointer(&b[0:SizeofXfrmId][0]))
-}
-
-func (msg *XfrmId) Serialize() []byte {
- return (*(*[SizeofXfrmId]byte)(unsafe.Pointer(msg)))[:]
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_policy_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_policy_linux.go
deleted file mode 100644
index 66f7e03d..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_policy_linux.go
+++ /dev/null
@@ -1,119 +0,0 @@
-package nl
-
-import (
- "unsafe"
-)
-
-const (
- SizeofXfrmUserpolicyId = 0x40
- SizeofXfrmUserpolicyInfo = 0xa8
- SizeofXfrmUserTmpl = 0x40
-)
-
-// struct xfrm_userpolicy_id {
-// struct xfrm_selector sel;
-// __u32 index;
-// __u8 dir;
-// };
-//
-
-type XfrmUserpolicyId struct {
- Sel XfrmSelector
- Index uint32
- Dir uint8
- Pad [3]byte
-}
-
-func (msg *XfrmUserpolicyId) Len() int {
- return SizeofXfrmUserpolicyId
-}
-
-func DeserializeXfrmUserpolicyId(b []byte) *XfrmUserpolicyId {
- return (*XfrmUserpolicyId)(unsafe.Pointer(&b[0:SizeofXfrmUserpolicyId][0]))
-}
-
-func (msg *XfrmUserpolicyId) Serialize() []byte {
- return (*(*[SizeofXfrmUserpolicyId]byte)(unsafe.Pointer(msg)))[:]
-}
-
-// struct xfrm_userpolicy_info {
-// struct xfrm_selector sel;
-// struct xfrm_lifetime_cfg lft;
-// struct xfrm_lifetime_cur curlft;
-// __u32 priority;
-// __u32 index;
-// __u8 dir;
-// __u8 action;
-// #define XFRM_POLICY_ALLOW 0
-// #define XFRM_POLICY_BLOCK 1
-// __u8 flags;
-// #define XFRM_POLICY_LOCALOK 1 /* Allow user to override global policy */
-// /* Automatically expand selector to include matching ICMP payloads. */
-// #define XFRM_POLICY_ICMP 2
-// __u8 share;
-// };
-
-type XfrmUserpolicyInfo struct {
- Sel XfrmSelector
- Lft XfrmLifetimeCfg
- Curlft XfrmLifetimeCur
- Priority uint32
- Index uint32
- Dir uint8
- Action uint8
- Flags uint8
- Share uint8
- Pad [4]byte
-}
-
-func (msg *XfrmUserpolicyInfo) Len() int {
- return SizeofXfrmUserpolicyInfo
-}
-
-func DeserializeXfrmUserpolicyInfo(b []byte) *XfrmUserpolicyInfo {
- return (*XfrmUserpolicyInfo)(unsafe.Pointer(&b[0:SizeofXfrmUserpolicyInfo][0]))
-}
-
-func (msg *XfrmUserpolicyInfo) Serialize() []byte {
- return (*(*[SizeofXfrmUserpolicyInfo]byte)(unsafe.Pointer(msg)))[:]
-}
-
-// struct xfrm_user_tmpl {
-// struct xfrm_id id;
-// __u16 family;
-// xfrm_address_t saddr;
-// __u32 reqid;
-// __u8 mode;
-// __u8 share;
-// __u8 optional;
-// __u32 aalgos;
-// __u32 ealgos;
-// __u32 calgos;
-// }
-
-type XfrmUserTmpl struct {
- XfrmId XfrmId
- Family uint16
- Pad1 [2]byte
- Saddr XfrmAddress
- Reqid uint32
- Mode uint8
- Share uint8
- Optional uint8
- Pad2 byte
- Aalgos uint32
- Ealgos uint32
- Calgos uint32
-}
-
-func (msg *XfrmUserTmpl) Len() int {
- return SizeofXfrmUserTmpl
-}
-
-func DeserializeXfrmUserTmpl(b []byte) *XfrmUserTmpl {
- return (*XfrmUserTmpl)(unsafe.Pointer(&b[0:SizeofXfrmUserTmpl][0]))
-}
-
-func (msg *XfrmUserTmpl) Serialize() []byte {
- return (*(*[SizeofXfrmUserTmpl]byte)(unsafe.Pointer(msg)))[:]
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_state_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_state_linux.go
deleted file mode 100644
index 4876ce45..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_state_linux.go
+++ /dev/null
@@ -1,221 +0,0 @@
-package nl
-
-import (
- "unsafe"
-)
-
-const (
- SizeofXfrmUsersaId = 0x18
- SizeofXfrmStats = 0x0c
- SizeofXfrmUsersaInfo = 0xe0
- SizeofXfrmAlgo = 0x44
- SizeofXfrmAlgoAuth = 0x48
- SizeofXfrmEncapTmpl = 0x18
-)
-
-// struct xfrm_usersa_id {
-// xfrm_address_t daddr;
-// __be32 spi;
-// __u16 family;
-// __u8 proto;
-// };
-
-type XfrmUsersaId struct {
- Daddr XfrmAddress
- Spi uint32 // big endian
- Family uint16
- Proto uint8
- Pad byte
-}
-
-func (msg *XfrmUsersaId) Len() int {
- return SizeofXfrmUsersaId
-}
-
-func DeserializeXfrmUsersaId(b []byte) *XfrmUsersaId {
- return (*XfrmUsersaId)(unsafe.Pointer(&b[0:SizeofXfrmUsersaId][0]))
-}
-
-func (msg *XfrmUsersaId) Serialize() []byte {
- return (*(*[SizeofXfrmUsersaId]byte)(unsafe.Pointer(msg)))[:]
-}
-
-// struct xfrm_stats {
-// __u32 replay_window;
-// __u32 replay;
-// __u32 integrity_failed;
-// };
-
-type XfrmStats struct {
- ReplayWindow uint32
- Replay uint32
- IntegrityFailed uint32
-}
-
-func (msg *XfrmStats) Len() int {
- return SizeofXfrmStats
-}
-
-func DeserializeXfrmStats(b []byte) *XfrmStats {
- return (*XfrmStats)(unsafe.Pointer(&b[0:SizeofXfrmStats][0]))
-}
-
-func (msg *XfrmStats) Serialize() []byte {
- return (*(*[SizeofXfrmStats]byte)(unsafe.Pointer(msg)))[:]
-}
-
-// struct xfrm_usersa_info {
-// struct xfrm_selector sel;
-// struct xfrm_id id;
-// xfrm_address_t saddr;
-// struct xfrm_lifetime_cfg lft;
-// struct xfrm_lifetime_cur curlft;
-// struct xfrm_stats stats;
-// __u32 seq;
-// __u32 reqid;
-// __u16 family;
-// __u8 mode; /* XFRM_MODE_xxx */
-// __u8 replay_window;
-// __u8 flags;
-// #define XFRM_STATE_NOECN 1
-// #define XFRM_STATE_DECAP_DSCP 2
-// #define XFRM_STATE_NOPMTUDISC 4
-// #define XFRM_STATE_WILDRECV 8
-// #define XFRM_STATE_ICMP 16
-// #define XFRM_STATE_AF_UNSPEC 32
-// #define XFRM_STATE_ALIGN4 64
-// #define XFRM_STATE_ESN 128
-// };
-//
-// #define XFRM_SA_XFLAG_DONT_ENCAP_DSCP 1
-//
-
-type XfrmUsersaInfo struct {
- Sel XfrmSelector
- Id XfrmId
- Saddr XfrmAddress
- Lft XfrmLifetimeCfg
- Curlft XfrmLifetimeCur
- Stats XfrmStats
- Seq uint32
- Reqid uint32
- Family uint16
- Mode uint8
- ReplayWindow uint8
- Flags uint8
- Pad [7]byte
-}
-
-func (msg *XfrmUsersaInfo) Len() int {
- return SizeofXfrmUsersaInfo
-}
-
-func DeserializeXfrmUsersaInfo(b []byte) *XfrmUsersaInfo {
- return (*XfrmUsersaInfo)(unsafe.Pointer(&b[0:SizeofXfrmUsersaInfo][0]))
-}
-
-func (msg *XfrmUsersaInfo) Serialize() []byte {
- return (*(*[SizeofXfrmUsersaInfo]byte)(unsafe.Pointer(msg)))[:]
-}
-
-// struct xfrm_algo {
-// char alg_name[64];
-// unsigned int alg_key_len; /* in bits */
-// char alg_key[0];
-// };
-
-type XfrmAlgo struct {
- AlgName [64]byte
- AlgKeyLen uint32
- AlgKey []byte
-}
-
-func (msg *XfrmAlgo) Len() int {
- return SizeofXfrmAlgo + int(msg.AlgKeyLen/8)
-}
-
-func DeserializeXfrmAlgo(b []byte) *XfrmAlgo {
- ret := XfrmAlgo{}
- copy(ret.AlgName[:], b[0:64])
- ret.AlgKeyLen = *(*uint32)(unsafe.Pointer(&b[64]))
- ret.AlgKey = b[68:ret.Len()]
- return &ret
-}
-
-func (msg *XfrmAlgo) Serialize() []byte {
- b := make([]byte, msg.Len())
- copy(b[0:64], msg.AlgName[:])
- copy(b[64:68], (*(*[4]byte)(unsafe.Pointer(&msg.AlgKeyLen)))[:])
- copy(b[68:msg.Len()], msg.AlgKey[:])
- return b
-}
-
-// struct xfrm_algo_auth {
-// char alg_name[64];
-// unsigned int alg_key_len; /* in bits */
-// unsigned int alg_trunc_len; /* in bits */
-// char alg_key[0];
-// };
-
-type XfrmAlgoAuth struct {
- AlgName [64]byte
- AlgKeyLen uint32
- AlgTruncLen uint32
- AlgKey []byte
-}
-
-func (msg *XfrmAlgoAuth) Len() int {
- return SizeofXfrmAlgoAuth + int(msg.AlgKeyLen/8)
-}
-
-func DeserializeXfrmAlgoAuth(b []byte) *XfrmAlgoAuth {
- ret := XfrmAlgoAuth{}
- copy(ret.AlgName[:], b[0:64])
- ret.AlgKeyLen = *(*uint32)(unsafe.Pointer(&b[64]))
- ret.AlgTruncLen = *(*uint32)(unsafe.Pointer(&b[68]))
- ret.AlgKey = b[72:ret.Len()]
- return &ret
-}
-
-func (msg *XfrmAlgoAuth) Serialize() []byte {
- b := make([]byte, msg.Len())
- copy(b[0:64], msg.AlgName[:])
- copy(b[64:68], (*(*[4]byte)(unsafe.Pointer(&msg.AlgKeyLen)))[:])
- copy(b[68:72], (*(*[4]byte)(unsafe.Pointer(&msg.AlgTruncLen)))[:])
- copy(b[72:msg.Len()], msg.AlgKey[:])
- return b
-}
-
-// struct xfrm_algo_aead {
-// char alg_name[64];
-// unsigned int alg_key_len; /* in bits */
-// unsigned int alg_icv_len; /* in bits */
-// char alg_key[0];
-// }
-
-// struct xfrm_encap_tmpl {
-// __u16 encap_type;
-// __be16 encap_sport;
-// __be16 encap_dport;
-// xfrm_address_t encap_oa;
-// };
-
-type XfrmEncapTmpl struct {
- EncapType uint16
- EncapSport uint16 // big endian
- EncapDport uint16 // big endian
- Pad [2]byte
- EncapOa XfrmAddress
-}
-
-func (msg *XfrmEncapTmpl) Len() int {
- return SizeofXfrmEncapTmpl
-}
-
-func DeserializeXfrmEncapTmpl(b []byte) *XfrmEncapTmpl {
- return (*XfrmEncapTmpl)(unsafe.Pointer(&b[0:SizeofXfrmEncapTmpl][0]))
-}
-
-func (msg *XfrmEncapTmpl) Serialize() []byte {
- return (*(*[SizeofXfrmEncapTmpl]byte)(unsafe.Pointer(msg)))[:]
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/protinfo.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/protinfo.go
deleted file mode 100644
index f39ab8f4..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/protinfo.go
+++ /dev/null
@@ -1,53 +0,0 @@
-package netlink
-
-import (
- "strings"
-)
-
-// Protinfo represents bridge flags from netlink.
-type Protinfo struct {
- Hairpin bool
- Guard bool
- FastLeave bool
- RootBlock bool
- Learning bool
- Flood bool
-}
-
-// String returns a list of enabled flags
-func (prot *Protinfo) String() string {
- var boolStrings []string
- if prot.Hairpin {
- boolStrings = append(boolStrings, "Hairpin")
- }
- if prot.Guard {
- boolStrings = append(boolStrings, "Guard")
- }
- if prot.FastLeave {
- boolStrings = append(boolStrings, "FastLeave")
- }
- if prot.RootBlock {
- boolStrings = append(boolStrings, "RootBlock")
- }
- if prot.Learning {
- boolStrings = append(boolStrings, "Learning")
- }
- if prot.Flood {
- boolStrings = append(boolStrings, "Flood")
- }
- return strings.Join(boolStrings, " ")
-}
-
-func boolToByte(x bool) []byte {
- if x {
- return []byte{1}
- }
- return []byte{0}
-}
-
-func byteToBool(x byte) bool {
- if uint8(x) != 0 {
- return true
- }
- return false
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/protinfo_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/protinfo_linux.go
deleted file mode 100644
index 7181eba1..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/protinfo_linux.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package netlink
-
-import (
- "fmt"
- "syscall"
-
- "github.com/vishvananda/netlink/nl"
-)
-
-func LinkGetProtinfo(link Link) (Protinfo, error) {
- base := link.Attrs()
- ensureIndex(base)
- var pi Protinfo
- req := nl.NewNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_DUMP)
- msg := nl.NewIfInfomsg(syscall.AF_BRIDGE)
- req.AddData(msg)
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- if err != nil {
- return pi, err
- }
-
- for _, m := range msgs {
- ans := nl.DeserializeIfInfomsg(m)
- if int(ans.Index) != base.Index {
- continue
- }
- attrs, err := nl.ParseRouteAttr(m[ans.Len():])
- if err != nil {
- return pi, err
- }
- for _, attr := range attrs {
- if attr.Attr.Type != syscall.IFLA_PROTINFO|syscall.NLA_F_NESTED {
- continue
- }
- infos, err := nl.ParseRouteAttr(attr.Value)
- if err != nil {
- return pi, err
- }
- var pi Protinfo
- for _, info := range infos {
- switch info.Attr.Type {
- case nl.IFLA_BRPORT_MODE:
- pi.Hairpin = byteToBool(info.Value[0])
- case nl.IFLA_BRPORT_GUARD:
- pi.Guard = byteToBool(info.Value[0])
- case nl.IFLA_BRPORT_FAST_LEAVE:
- pi.FastLeave = byteToBool(info.Value[0])
- case nl.IFLA_BRPORT_PROTECT:
- pi.RootBlock = byteToBool(info.Value[0])
- case nl.IFLA_BRPORT_LEARNING:
- pi.Learning = byteToBool(info.Value[0])
- case nl.IFLA_BRPORT_UNICAST_FLOOD:
- pi.Flood = byteToBool(info.Value[0])
- }
- }
- return pi, nil
- }
- }
- return pi, fmt.Errorf("Device with index %d not found", base.Index)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/qdisc.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/qdisc.go
deleted file mode 100644
index 8e3d020f..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/qdisc.go
+++ /dev/null
@@ -1,138 +0,0 @@
-package netlink
-
-import (
- "fmt"
-)
-
-const (
- HANDLE_NONE = 0
- HANDLE_INGRESS = 0xFFFFFFF1
- HANDLE_ROOT = 0xFFFFFFFF
- PRIORITY_MAP_LEN = 16
-)
-
-type Qdisc interface {
- Attrs() *QdiscAttrs
- Type() string
-}
-
-// Qdisc represents a netlink qdisc. A qdisc is associated with a link,
-// has a handle, a parent and a refcnt. The root qdisc of a device should
-// have parent == HANDLE_ROOT.
-type QdiscAttrs struct {
- LinkIndex int
- Handle uint32
- Parent uint32
- Refcnt uint32 // read only
-}
-
-func (q QdiscAttrs) String() string {
- return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Refcnt: %s}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Refcnt)
-}
-
-func MakeHandle(major, minor uint16) uint32 {
- return (uint32(major) << 16) | uint32(minor)
-}
-
-func MajorMinor(handle uint32) (uint16, uint16) {
- return uint16((handle & 0xFFFF0000) >> 16), uint16(handle & 0x0000FFFFF)
-}
-
-func HandleStr(handle uint32) string {
- switch handle {
- case HANDLE_NONE:
- return "none"
- case HANDLE_INGRESS:
- return "ingress"
- case HANDLE_ROOT:
- return "root"
- default:
- major, minor := MajorMinor(handle)
- return fmt.Sprintf("%x:%x", major, minor)
- }
-}
-
-// PfifoFast is the default qdisc created by the kernel if one has not
-// been defined for the interface
-type PfifoFast struct {
- QdiscAttrs
- Bands uint8
- PriorityMap [PRIORITY_MAP_LEN]uint8
-}
-
-func (qdisc *PfifoFast) Attrs() *QdiscAttrs {
- return &qdisc.QdiscAttrs
-}
-
-func (qdisc *PfifoFast) Type() string {
- return "pfifo_fast"
-}
-
-// Prio is a basic qdisc that works just like PfifoFast
-type Prio struct {
- QdiscAttrs
- Bands uint8
- PriorityMap [PRIORITY_MAP_LEN]uint8
-}
-
-func NewPrio(attrs QdiscAttrs) *Prio {
- return &Prio{
- QdiscAttrs: attrs,
- Bands: 3,
- PriorityMap: [PRIORITY_MAP_LEN]uint8{1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
- }
-}
-
-func (qdisc *Prio) Attrs() *QdiscAttrs {
- return &qdisc.QdiscAttrs
-}
-
-func (qdisc *Prio) Type() string {
- return "prio"
-}
-
-// Tbf is a classful qdisc that rate limits based on tokens
-type Tbf struct {
- QdiscAttrs
- // TODO: handle 64bit rate properly
- Rate uint64
- Limit uint32
- Buffer uint32
- // TODO: handle other settings
-}
-
-func (qdisc *Tbf) Attrs() *QdiscAttrs {
- return &qdisc.QdiscAttrs
-}
-
-func (qdisc *Tbf) Type() string {
- return "tbf"
-}
-
-// Ingress is a qdisc for adding ingress filters
-type Ingress struct {
- QdiscAttrs
-}
-
-func (qdisc *Ingress) Attrs() *QdiscAttrs {
- return &qdisc.QdiscAttrs
-}
-
-func (qdisc *Ingress) Type() string {
- return "ingress"
-}
-
-// GenericQdisc qdiscs represent types that are not currently understood
-// by this netlink library.
-type GenericQdisc struct {
- QdiscAttrs
- QdiscType string
-}
-
-func (qdisc *GenericQdisc) Attrs() *QdiscAttrs {
- return &qdisc.QdiscAttrs
-}
-
-func (qdisc *GenericQdisc) Type() string {
- return qdisc.QdiscType
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/qdisc_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/qdisc_linux.go
deleted file mode 100644
index 2531c9dd..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/qdisc_linux.go
+++ /dev/null
@@ -1,263 +0,0 @@
-package netlink
-
-import (
- "fmt"
- "io/ioutil"
- "strconv"
- "strings"
- "syscall"
-
- "github.com/vishvananda/netlink/nl"
-)
-
-// QdiscDel will delete a qdisc from the system.
-// Equivalent to: `tc qdisc del $qdisc`
-func QdiscDel(qdisc Qdisc) error {
- req := nl.NewNetlinkRequest(syscall.RTM_DELQDISC, syscall.NLM_F_ACK)
- base := qdisc.Attrs()
- msg := &nl.TcMsg{
- Family: nl.FAMILY_ALL,
- Ifindex: int32(base.LinkIndex),
- Handle: base.Handle,
- Parent: base.Parent,
- }
- req.AddData(msg)
-
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- return err
-}
-
-// QdiscAdd will add a qdisc to the system.
-// Equivalent to: `tc qdisc add $qdisc`
-func QdiscAdd(qdisc Qdisc) error {
- req := nl.NewNetlinkRequest(syscall.RTM_NEWQDISC, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
- base := qdisc.Attrs()
- msg := &nl.TcMsg{
- Family: nl.FAMILY_ALL,
- Ifindex: int32(base.LinkIndex),
- Handle: base.Handle,
- Parent: base.Parent,
- }
- req.AddData(msg)
- req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(qdisc.Type())))
-
- options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)
- if prio, ok := qdisc.(*Prio); ok {
- tcmap := nl.TcPrioMap{
- Bands: int32(prio.Bands),
- Priomap: prio.PriorityMap,
- }
- options = nl.NewRtAttr(nl.TCA_OPTIONS, tcmap.Serialize())
- } else if tbf, ok := qdisc.(*Tbf); ok {
- opt := nl.TcTbfQopt{}
- // TODO: handle rate > uint32
- opt.Rate.Rate = uint32(tbf.Rate)
- opt.Limit = tbf.Limit
- opt.Buffer = tbf.Buffer
- nl.NewRtAttrChild(options, nl.TCA_TBF_PARMS, opt.Serialize())
- } else if _, ok := qdisc.(*Ingress); ok {
- // ingress filters must use the proper handle
- if msg.Parent != HANDLE_INGRESS {
- return fmt.Errorf("Ingress filters must set Parent to HANDLE_INGRESS")
- }
- }
- req.AddData(options)
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- return err
-}
-
-// QdiscList gets a list of qdiscs in the system.
-// Equivalent to: `tc qdisc show`.
-// The list can be filtered by link.
-func QdiscList(link Link) ([]Qdisc, error) {
- req := nl.NewNetlinkRequest(syscall.RTM_GETQDISC, syscall.NLM_F_DUMP)
- index := int32(0)
- if link != nil {
- base := link.Attrs()
- ensureIndex(base)
- index = int32(base.Index)
- }
- msg := &nl.TcMsg{
- Family: nl.FAMILY_ALL,
- Ifindex: index,
- }
- req.AddData(msg)
-
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWQDISC)
- if err != nil {
- return nil, err
- }
-
- var res []Qdisc
- for _, m := range msgs {
- msg := nl.DeserializeTcMsg(m)
-
- attrs, err := nl.ParseRouteAttr(m[msg.Len():])
- if err != nil {
- return nil, err
- }
-
- // skip qdiscs from other interfaces
- if link != nil && msg.Ifindex != index {
- continue
- }
-
- base := QdiscAttrs{
- LinkIndex: int(msg.Ifindex),
- Handle: msg.Handle,
- Parent: msg.Parent,
- Refcnt: msg.Info,
- }
- var qdisc Qdisc
- qdiscType := ""
- for _, attr := range attrs {
- switch attr.Attr.Type {
- case nl.TCA_KIND:
- qdiscType = string(attr.Value[:len(attr.Value)-1])
- switch qdiscType {
- case "pfifo_fast":
- qdisc = &PfifoFast{}
- case "prio":
- qdisc = &Prio{}
- case "tbf":
- qdisc = &Tbf{}
- case "ingress":
- qdisc = &Ingress{}
- default:
- qdisc = &GenericQdisc{QdiscType: qdiscType}
- }
- case nl.TCA_OPTIONS:
- switch qdiscType {
- case "pfifo_fast":
- // pfifo returns TcPrioMap directly without wrapping it in rtattr
- if err := parsePfifoFastData(qdisc, attr.Value); err != nil {
- return nil, err
- }
- case "prio":
- // prio returns TcPrioMap directly without wrapping it in rtattr
- if err := parsePrioData(qdisc, attr.Value); err != nil {
- return nil, err
- }
- case "tbf":
- data, err := nl.ParseRouteAttr(attr.Value)
- if err != nil {
- return nil, err
- }
- if err := parseTbfData(qdisc, data); err != nil {
- return nil, err
- }
- // no options for ingress
- }
- }
- }
- *qdisc.Attrs() = base
- res = append(res, qdisc)
- }
-
- return res, nil
-}
-
-func parsePfifoFastData(qdisc Qdisc, value []byte) error {
- pfifo := qdisc.(*PfifoFast)
- tcmap := nl.DeserializeTcPrioMap(value)
- pfifo.PriorityMap = tcmap.Priomap
- pfifo.Bands = uint8(tcmap.Bands)
- return nil
-}
-
-func parsePrioData(qdisc Qdisc, value []byte) error {
- prio := qdisc.(*Prio)
- tcmap := nl.DeserializeTcPrioMap(value)
- prio.PriorityMap = tcmap.Priomap
- prio.Bands = uint8(tcmap.Bands)
- return nil
-}
-
-func parseTbfData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
- native = nl.NativeEndian()
- tbf := qdisc.(*Tbf)
- for _, datum := range data {
- switch datum.Attr.Type {
- case nl.TCA_TBF_PARMS:
- opt := nl.DeserializeTcTbfQopt(datum.Value)
- tbf.Rate = uint64(opt.Rate.Rate)
- tbf.Limit = opt.Limit
- tbf.Buffer = opt.Buffer
- case nl.TCA_TBF_RATE64:
- tbf.Rate = native.Uint64(datum.Value[0:4])
- }
- }
- return nil
-}
-
-const (
- TIME_UNITS_PER_SEC = 1000000
-)
-
-var (
- tickInUsec float64 = 0.0
- clockFactor float64 = 0.0
-)
-
-func initClock() {
- data, err := ioutil.ReadFile("/proc/net/psched")
- if err != nil {
- return
- }
- parts := strings.Split(strings.TrimSpace(string(data)), " ")
- if len(parts) < 3 {
- return
- }
- var vals [3]uint64
- for i := range vals {
- val, err := strconv.ParseUint(parts[i], 16, 32)
- if err != nil {
- return
- }
- vals[i] = val
- }
- // compatibility
- if vals[2] == 1000000000 {
- vals[0] = vals[1]
- }
- clockFactor = float64(vals[2]) / TIME_UNITS_PER_SEC
- tickInUsec = float64(vals[0]) / float64(vals[1]) * clockFactor
-}
-
-func TickInUsec() float64 {
- if tickInUsec == 0.0 {
- initClock()
- }
- return tickInUsec
-}
-
-func ClockFactor() float64 {
- if clockFactor == 0.0 {
- initClock()
- }
- return clockFactor
-}
-
-func time2Tick(time uint32) uint32 {
- return uint32(float64(time) * TickInUsec())
-}
-
-func tick2Time(tick uint32) uint32 {
- return uint32(float64(tick) / TickInUsec())
-}
-
-func time2Ktime(time uint32) uint32 {
- return uint32(float64(time) * ClockFactor())
-}
-
-func ktime2Time(ktime uint32) uint32 {
- return uint32(float64(ktime) / ClockFactor())
-}
-
-func burst(rate uint64, buffer uint32) uint32 {
- return uint32(float64(rate) * float64(tick2Time(buffer)) / TIME_UNITS_PER_SEC)
-}
-
-func latency(rate uint64, limit, buffer uint32) float64 {
- return TIME_UNITS_PER_SEC*(float64(limit)/float64(rate)) - float64(tick2Time(buffer))
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/route.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/route.go
deleted file mode 100644
index 6218546f..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/route.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package netlink
-
-import (
- "fmt"
- "net"
- "syscall"
-)
-
-// Scope is an enum representing a route scope.
-type Scope uint8
-
-const (
- SCOPE_UNIVERSE Scope = syscall.RT_SCOPE_UNIVERSE
- SCOPE_SITE Scope = syscall.RT_SCOPE_SITE
- SCOPE_LINK Scope = syscall.RT_SCOPE_LINK
- SCOPE_HOST Scope = syscall.RT_SCOPE_HOST
- SCOPE_NOWHERE Scope = syscall.RT_SCOPE_NOWHERE
-)
-
-// Route represents a netlink route. A route is associated with a link,
-// has a destination network, an optional source ip, and optional
-// gateway. Advanced route parameters and non-main routing tables are
-// currently not supported.
-type Route struct {
- LinkIndex int
- Scope Scope
- Dst *net.IPNet
- Src net.IP
- Gw net.IP
-}
-
-func (r Route) String() string {
- return fmt.Sprintf("{Ifindex: %d Dst: %s Src: %s Gw: %s}", r.LinkIndex, r.Dst,
- r.Src, r.Gw)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/route_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/route_linux.go
deleted file mode 100644
index 9e76d441..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/route_linux.go
+++ /dev/null
@@ -1,225 +0,0 @@
-package netlink
-
-import (
- "fmt"
- "net"
- "syscall"
-
- "github.com/vishvananda/netlink/nl"
-)
-
-// RtAttr is shared so it is in netlink_linux.go
-
-// RouteAdd will add a route to the system.
-// Equivalent to: `ip route add $route`
-func RouteAdd(route *Route) error {
- req := nl.NewNetlinkRequest(syscall.RTM_NEWROUTE, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
- return routeHandle(route, req, nl.NewRtMsg())
-}
-
-// RouteAdd will delete a route from the system.
-// Equivalent to: `ip route del $route`
-func RouteDel(route *Route) error {
- req := nl.NewNetlinkRequest(syscall.RTM_DELROUTE, syscall.NLM_F_ACK)
- return routeHandle(route, req, nl.NewRtDelMsg())
-}
-
-func routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg) error {
- if (route.Dst == nil || route.Dst.IP == nil) && route.Src == nil && route.Gw == nil {
- return fmt.Errorf("one of Dst.IP, Src, or Gw must not be nil")
- }
-
- msg.Scope = uint8(route.Scope)
- family := -1
- var rtAttrs []*nl.RtAttr
-
- if route.Dst != nil && route.Dst.IP != nil {
- dstLen, _ := route.Dst.Mask.Size()
- msg.Dst_len = uint8(dstLen)
- dstFamily := nl.GetIPFamily(route.Dst.IP)
- family = dstFamily
- var dstData []byte
- if dstFamily == FAMILY_V4 {
- dstData = route.Dst.IP.To4()
- } else {
- dstData = route.Dst.IP.To16()
- }
- rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_DST, dstData))
- }
-
- if route.Src != nil {
- srcFamily := nl.GetIPFamily(route.Src)
- if family != -1 && family != srcFamily {
- return fmt.Errorf("source and destination ip are not the same IP family")
- }
- family = srcFamily
- var srcData []byte
- if srcFamily == FAMILY_V4 {
- srcData = route.Src.To4()
- } else {
- srcData = route.Src.To16()
- }
- // The commonly used src ip for routes is actually PREFSRC
- rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_PREFSRC, srcData))
- }
-
- if route.Gw != nil {
- gwFamily := nl.GetIPFamily(route.Gw)
- if family != -1 && family != gwFamily {
- return fmt.Errorf("gateway, source, and destination ip are not the same IP family")
- }
- family = gwFamily
- var gwData []byte
- if gwFamily == FAMILY_V4 {
- gwData = route.Gw.To4()
- } else {
- gwData = route.Gw.To16()
- }
- rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_GATEWAY, gwData))
- }
-
- msg.Family = uint8(family)
-
- req.AddData(msg)
- for _, attr := range rtAttrs {
- req.AddData(attr)
- }
-
- var (
- b = make([]byte, 4)
- native = nl.NativeEndian()
- )
- native.PutUint32(b, uint32(route.LinkIndex))
-
- req.AddData(nl.NewRtAttr(syscall.RTA_OIF, b))
-
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
- return err
-}
-
-// RouteList gets a list of routes in the system.
-// Equivalent to: `ip route show`.
-// The list can be filtered by link and ip family.
-func RouteList(link Link, family int) ([]Route, error) {
- req := nl.NewNetlinkRequest(syscall.RTM_GETROUTE, syscall.NLM_F_DUMP)
- msg := nl.NewIfInfomsg(family)
- req.AddData(msg)
-
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWROUTE)
- if err != nil {
- return nil, err
- }
-
- index := 0
- if link != nil {
- base := link.Attrs()
- ensureIndex(base)
- index = base.Index
- }
-
- native := nl.NativeEndian()
- var res []Route
-MsgLoop:
- for _, m := range msgs {
- msg := nl.DeserializeRtMsg(m)
-
- if msg.Flags&syscall.RTM_F_CLONED != 0 {
- // Ignore cloned routes
- continue
- }
-
- if msg.Table != syscall.RT_TABLE_MAIN {
- // Ignore non-main tables
- continue
- }
-
- attrs, err := nl.ParseRouteAttr(m[msg.Len():])
- if err != nil {
- return nil, err
- }
-
- route := Route{Scope: Scope(msg.Scope)}
- for _, attr := range attrs {
- switch attr.Attr.Type {
- case syscall.RTA_GATEWAY:
- route.Gw = net.IP(attr.Value)
- case syscall.RTA_PREFSRC:
- route.Src = net.IP(attr.Value)
- case syscall.RTA_DST:
- route.Dst = &net.IPNet{
- IP: attr.Value,
- Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)),
- }
- case syscall.RTA_OIF:
- routeIndex := int(native.Uint32(attr.Value[0:4]))
- if link != nil && routeIndex != index {
- // Ignore routes from other interfaces
- continue MsgLoop
- }
- route.LinkIndex = routeIndex
- }
- }
- res = append(res, route)
- }
-
- return res, nil
-}
-
-// RouteGet gets a route to a specific destination from the host system.
-// Equivalent to: 'ip route get'.
-func RouteGet(destination net.IP) ([]Route, error) {
- req := nl.NewNetlinkRequest(syscall.RTM_GETROUTE, syscall.NLM_F_REQUEST)
- family := nl.GetIPFamily(destination)
- var destinationData []byte
- var bitlen uint8
- if family == FAMILY_V4 {
- destinationData = destination.To4()
- bitlen = 32
- } else {
- destinationData = destination.To16()
- bitlen = 128
- }
- msg := &nl.RtMsg{}
- msg.Family = uint8(family)
- msg.Dst_len = bitlen
- req.AddData(msg)
-
- rtaDst := nl.NewRtAttr(syscall.RTA_DST, destinationData)
- req.AddData(rtaDst)
-
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWROUTE)
- if err != nil {
- return nil, err
- }
-
- native := nl.NativeEndian()
- var res []Route
- for _, m := range msgs {
- msg := nl.DeserializeRtMsg(m)
- attrs, err := nl.ParseRouteAttr(m[msg.Len():])
- if err != nil {
- return nil, err
- }
-
- route := Route{}
- for _, attr := range attrs {
- switch attr.Attr.Type {
- case syscall.RTA_GATEWAY:
- route.Gw = net.IP(attr.Value)
- case syscall.RTA_PREFSRC:
- route.Src = net.IP(attr.Value)
- case syscall.RTA_DST:
- route.Dst = &net.IPNet{
- IP: attr.Value,
- Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)),
- }
- case syscall.RTA_OIF:
- routeIndex := int(native.Uint32(attr.Value[0:4]))
- route.LinkIndex = routeIndex
- }
- }
- res = append(res, route)
- }
- return res, nil
-
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm.go
deleted file mode 100644
index 621ffb6c..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package netlink
-
-import (
- "fmt"
- "syscall"
-)
-
-// Proto is an enum representing an ipsec protocol.
-type Proto uint8
-
-const (
- XFRM_PROTO_ROUTE2 Proto = syscall.IPPROTO_ROUTING
- XFRM_PROTO_ESP Proto = syscall.IPPROTO_ESP
- XFRM_PROTO_AH Proto = syscall.IPPROTO_AH
- XFRM_PROTO_HAO Proto = syscall.IPPROTO_DSTOPTS
- XFRM_PROTO_COMP Proto = syscall.IPPROTO_COMP
- XFRM_PROTO_IPSEC_ANY Proto = syscall.IPPROTO_RAW
-)
-
-func (p Proto) String() string {
- switch p {
- case XFRM_PROTO_ROUTE2:
- return "route2"
- case XFRM_PROTO_ESP:
- return "esp"
- case XFRM_PROTO_AH:
- return "ah"
- case XFRM_PROTO_HAO:
- return "hao"
- case XFRM_PROTO_COMP:
- return "comp"
- case XFRM_PROTO_IPSEC_ANY:
- return "ipsec-any"
- }
- return fmt.Sprintf("%d", p)
-}
-
-// Mode is an enum representing an ipsec transport.
-type Mode uint8
-
-const (
- XFRM_MODE_TRANSPORT Mode = iota
- XFRM_MODE_TUNNEL
- XFRM_MODE_ROUTEOPTIMIZATION
- XFRM_MODE_IN_TRIGGER
- XFRM_MODE_BEET
- XFRM_MODE_MAX
-)
-
-func (m Mode) String() string {
- switch m {
- case XFRM_MODE_TRANSPORT:
- return "transport"
- case XFRM_MODE_TUNNEL:
- return "tunnel"
- case XFRM_MODE_ROUTEOPTIMIZATION:
- return "ro"
- case XFRM_MODE_IN_TRIGGER:
- return "in_trigger"
- case XFRM_MODE_BEET:
- return "beet"
- }
- return fmt.Sprintf("%d", m)
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_policy.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_policy.go
deleted file mode 100644
index d85c65d2..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_policy.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package netlink
-
-import (
- "fmt"
- "net"
-)
-
-// Dir is an enum representing an ipsec template direction.
-type Dir uint8
-
-const (
- XFRM_DIR_IN Dir = iota
- XFRM_DIR_OUT
- XFRM_DIR_FWD
- XFRM_SOCKET_IN
- XFRM_SOCKET_OUT
- XFRM_SOCKET_FWD
-)
-
-func (d Dir) String() string {
- switch d {
- case XFRM_DIR_IN:
- return "dir in"
- case XFRM_DIR_OUT:
- return "dir out"
- case XFRM_DIR_FWD:
- return "dir fwd"
- case XFRM_SOCKET_IN:
- return "socket in"
- case XFRM_SOCKET_OUT:
- return "socket out"
- case XFRM_SOCKET_FWD:
- return "socket fwd"
- }
- return fmt.Sprintf("socket %d", d-XFRM_SOCKET_IN)
-}
-
-// XfrmPolicyTmpl encapsulates a rule for the base addresses of an ipsec
-// policy. These rules are matched with XfrmState to determine encryption
-// and authentication algorithms.
-type XfrmPolicyTmpl struct {
- Dst net.IP
- Src net.IP
- Proto Proto
- Mode Mode
- Reqid int
-}
-
-// XfrmPolicy represents an ipsec policy. It represents the overlay network
-// and has a list of XfrmPolicyTmpls representing the base addresses of
-// the policy.
-type XfrmPolicy struct {
- Dst *net.IPNet
- Src *net.IPNet
- Dir Dir
- Priority int
- Index int
- Tmpls []XfrmPolicyTmpl
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_policy_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_policy_linux.go
deleted file mode 100644
index 2daf6dc8..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_policy_linux.go
+++ /dev/null
@@ -1,127 +0,0 @@
-package netlink
-
-import (
- "syscall"
-
- "github.com/vishvananda/netlink/nl"
-)
-
-func selFromPolicy(sel *nl.XfrmSelector, policy *XfrmPolicy) {
- sel.Family = uint16(nl.GetIPFamily(policy.Dst.IP))
- sel.Daddr.FromIP(policy.Dst.IP)
- sel.Saddr.FromIP(policy.Src.IP)
- prefixlenD, _ := policy.Dst.Mask.Size()
- sel.PrefixlenD = uint8(prefixlenD)
- prefixlenS, _ := policy.Src.Mask.Size()
- sel.PrefixlenS = uint8(prefixlenS)
-}
-
-// XfrmPolicyAdd will add an xfrm policy to the system.
-// Equivalent to: `ip xfrm policy add $policy`
-func XfrmPolicyAdd(policy *XfrmPolicy) error {
- req := nl.NewNetlinkRequest(nl.XFRM_MSG_NEWPOLICY, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
-
- msg := &nl.XfrmUserpolicyInfo{}
- selFromPolicy(&msg.Sel, policy)
- msg.Priority = uint32(policy.Priority)
- msg.Index = uint32(policy.Index)
- msg.Dir = uint8(policy.Dir)
- msg.Lft.SoftByteLimit = nl.XFRM_INF
- msg.Lft.HardByteLimit = nl.XFRM_INF
- msg.Lft.SoftPacketLimit = nl.XFRM_INF
- msg.Lft.HardPacketLimit = nl.XFRM_INF
- req.AddData(msg)
-
- tmplData := make([]byte, nl.SizeofXfrmUserTmpl*len(policy.Tmpls))
- for i, tmpl := range policy.Tmpls {
- start := i * nl.SizeofXfrmUserTmpl
- userTmpl := nl.DeserializeXfrmUserTmpl(tmplData[start : start+nl.SizeofXfrmUserTmpl])
- userTmpl.XfrmId.Daddr.FromIP(tmpl.Dst)
- userTmpl.Saddr.FromIP(tmpl.Src)
- userTmpl.XfrmId.Proto = uint8(tmpl.Proto)
- userTmpl.Mode = uint8(tmpl.Mode)
- userTmpl.Reqid = uint32(tmpl.Reqid)
- userTmpl.Aalgos = ^uint32(0)
- userTmpl.Ealgos = ^uint32(0)
- userTmpl.Calgos = ^uint32(0)
- }
- if len(tmplData) > 0 {
- tmpls := nl.NewRtAttr(nl.XFRMA_TMPL, tmplData)
- req.AddData(tmpls)
- }
-
- _, err := req.Execute(syscall.NETLINK_XFRM, 0)
- return err
-}
-
-// XfrmPolicyDel will delete an xfrm policy from the system. Note that
-// the Tmpls are ignored when matching the policy to delete.
-// Equivalent to: `ip xfrm policy del $policy`
-func XfrmPolicyDel(policy *XfrmPolicy) error {
- req := nl.NewNetlinkRequest(nl.XFRM_MSG_DELPOLICY, syscall.NLM_F_ACK)
-
- msg := &nl.XfrmUserpolicyId{}
- selFromPolicy(&msg.Sel, policy)
- msg.Index = uint32(policy.Index)
- msg.Dir = uint8(policy.Dir)
- req.AddData(msg)
-
- _, err := req.Execute(syscall.NETLINK_XFRM, 0)
- return err
-}
-
-// XfrmPolicyList gets a list of xfrm policies in the system.
-// Equivalent to: `ip xfrm policy show`.
-// The list can be filtered by ip family.
-func XfrmPolicyList(family int) ([]XfrmPolicy, error) {
- req := nl.NewNetlinkRequest(nl.XFRM_MSG_GETPOLICY, syscall.NLM_F_DUMP)
-
- msg := nl.NewIfInfomsg(family)
- req.AddData(msg)
-
- msgs, err := req.Execute(syscall.NETLINK_XFRM, nl.XFRM_MSG_NEWPOLICY)
- if err != nil {
- return nil, err
- }
-
- var res []XfrmPolicy
- for _, m := range msgs {
- msg := nl.DeserializeXfrmUserpolicyInfo(m)
-
- if family != FAMILY_ALL && family != int(msg.Sel.Family) {
- continue
- }
-
- var policy XfrmPolicy
-
- policy.Dst = msg.Sel.Daddr.ToIPNet(msg.Sel.PrefixlenD)
- policy.Src = msg.Sel.Saddr.ToIPNet(msg.Sel.PrefixlenS)
- policy.Priority = int(msg.Priority)
- policy.Index = int(msg.Index)
- policy.Dir = Dir(msg.Dir)
-
- attrs, err := nl.ParseRouteAttr(m[msg.Len():])
- if err != nil {
- return nil, err
- }
-
- for _, attr := range attrs {
- switch attr.Attr.Type {
- case nl.XFRMA_TMPL:
- max := len(attr.Value)
- for i := 0; i < max; i += nl.SizeofXfrmUserTmpl {
- var resTmpl XfrmPolicyTmpl
- tmpl := nl.DeserializeXfrmUserTmpl(attr.Value[i : i+nl.SizeofXfrmUserTmpl])
- resTmpl.Dst = tmpl.XfrmId.Daddr.ToIP()
- resTmpl.Src = tmpl.Saddr.ToIP()
- resTmpl.Proto = Proto(tmpl.XfrmId.Proto)
- resTmpl.Mode = Mode(tmpl.Mode)
- resTmpl.Reqid = int(tmpl.Reqid)
- policy.Tmpls = append(policy.Tmpls, resTmpl)
- }
- }
- }
- res = append(res, policy)
- }
- return res, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_state.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_state.go
deleted file mode 100644
index 5b8f2df7..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_state.go
+++ /dev/null
@@ -1,53 +0,0 @@
-package netlink
-
-import (
- "net"
-)
-
-// XfrmStateAlgo represents the algorithm to use for the ipsec encryption.
-type XfrmStateAlgo struct {
- Name string
- Key []byte
- TruncateLen int // Auth only
-}
-
-// EncapType is an enum representing an ipsec template direction.
-type EncapType uint8
-
-const (
- XFRM_ENCAP_ESPINUDP_NONIKE EncapType = iota + 1
- XFRM_ENCAP_ESPINUDP
-)
-
-func (e EncapType) String() string {
- switch e {
- case XFRM_ENCAP_ESPINUDP_NONIKE:
- return "espinudp-nonike"
- case XFRM_ENCAP_ESPINUDP:
- return "espinudp"
- }
- return "unknown"
-}
-
-// XfrmEncap represents the encapsulation to use for the ipsec encryption.
-type XfrmStateEncap struct {
- Type EncapType
- SrcPort int
- DstPort int
- OriginalAddress net.IP
-}
-
-// XfrmState represents the state of an ipsec policy. It optionally
-// contains an XfrmStateAlgo for encryption and one for authentication.
-type XfrmState struct {
- Dst net.IP
- Src net.IP
- Proto Proto
- Mode Mode
- Spi int
- Reqid int
- ReplayWindow int
- Auth *XfrmStateAlgo
- Crypt *XfrmStateAlgo
- Encap *XfrmStateEncap
-}
diff --git a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_state_linux.go b/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_state_linux.go
deleted file mode 100644
index 5f44ec85..00000000
--- a/vendor/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_state_linux.go
+++ /dev/null
@@ -1,181 +0,0 @@
-package netlink
-
-import (
- "fmt"
- "syscall"
-
- "github.com/vishvananda/netlink/nl"
-)
-
-func writeStateAlgo(a *XfrmStateAlgo) []byte {
- algo := nl.XfrmAlgo{
- AlgKeyLen: uint32(len(a.Key) * 8),
- AlgKey: a.Key,
- }
- end := len(a.Name)
- if end > 64 {
- end = 64
- }
- copy(algo.AlgName[:end], a.Name)
- return algo.Serialize()
-}
-
-func writeStateAlgoAuth(a *XfrmStateAlgo) []byte {
- algo := nl.XfrmAlgoAuth{
- AlgKeyLen: uint32(len(a.Key) * 8),
- AlgTruncLen: uint32(a.TruncateLen),
- AlgKey: a.Key,
- }
- end := len(a.Name)
- if end > 64 {
- end = 64
- }
- copy(algo.AlgName[:end], a.Name)
- return algo.Serialize()
-}
-
-// XfrmStateAdd will add an xfrm state to the system.
-// Equivalent to: `ip xfrm state add $state`
-func XfrmStateAdd(state *XfrmState) error {
- // A state with spi 0 can't be deleted so don't allow it to be set
- if state.Spi == 0 {
- return fmt.Errorf("Spi must be set when adding xfrm state.")
- }
- req := nl.NewNetlinkRequest(nl.XFRM_MSG_NEWSA, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
-
- msg := &nl.XfrmUsersaInfo{}
- msg.Family = uint16(nl.GetIPFamily(state.Dst))
- msg.Id.Daddr.FromIP(state.Dst)
- msg.Saddr.FromIP(state.Src)
- msg.Id.Proto = uint8(state.Proto)
- msg.Mode = uint8(state.Mode)
- msg.Id.Spi = nl.Swap32(uint32(state.Spi))
- msg.Reqid = uint32(state.Reqid)
- msg.ReplayWindow = uint8(state.ReplayWindow)
- msg.Lft.SoftByteLimit = nl.XFRM_INF
- msg.Lft.HardByteLimit = nl.XFRM_INF
- msg.Lft.SoftPacketLimit = nl.XFRM_INF
- msg.Lft.HardPacketLimit = nl.XFRM_INF
- req.AddData(msg)
-
- if state.Auth != nil {
- out := nl.NewRtAttr(nl.XFRMA_ALG_AUTH_TRUNC, writeStateAlgoAuth(state.Auth))
- req.AddData(out)
- }
- if state.Crypt != nil {
- out := nl.NewRtAttr(nl.XFRMA_ALG_CRYPT, writeStateAlgo(state.Crypt))
- req.AddData(out)
- }
- if state.Encap != nil {
- encapData := make([]byte, nl.SizeofXfrmEncapTmpl)
- encap := nl.DeserializeXfrmEncapTmpl(encapData)
- encap.EncapType = uint16(state.Encap.Type)
- encap.EncapSport = nl.Swap16(uint16(state.Encap.SrcPort))
- encap.EncapDport = nl.Swap16(uint16(state.Encap.DstPort))
- encap.EncapOa.FromIP(state.Encap.OriginalAddress)
- out := nl.NewRtAttr(nl.XFRMA_ENCAP, encapData)
- req.AddData(out)
- }
-
- _, err := req.Execute(syscall.NETLINK_XFRM, 0)
- return err
-}
-
-// XfrmStateDel will delete an xfrm state from the system. Note that
-// the Algos are ignored when matching the state to delete.
-// Equivalent to: `ip xfrm state del $state`
-func XfrmStateDel(state *XfrmState) error {
- req := nl.NewNetlinkRequest(nl.XFRM_MSG_DELSA, syscall.NLM_F_ACK)
-
- msg := &nl.XfrmUsersaId{}
- msg.Daddr.FromIP(state.Dst)
- msg.Family = uint16(nl.GetIPFamily(state.Dst))
- msg.Proto = uint8(state.Proto)
- msg.Spi = nl.Swap32(uint32(state.Spi))
- req.AddData(msg)
-
- saddr := nl.XfrmAddress{}
- saddr.FromIP(state.Src)
- srcdata := nl.NewRtAttr(nl.XFRMA_SRCADDR, saddr.Serialize())
-
- req.AddData(srcdata)
-
- _, err := req.Execute(syscall.NETLINK_XFRM, 0)
- return err
-}
-
-// XfrmStateList gets a list of xfrm states in the system.
-// Equivalent to: `ip xfrm state show`.
-// The list can be filtered by ip family.
-func XfrmStateList(family int) ([]XfrmState, error) {
- req := nl.NewNetlinkRequest(nl.XFRM_MSG_GETSA, syscall.NLM_F_DUMP)
-
- msg := nl.NewIfInfomsg(family)
- req.AddData(msg)
-
- msgs, err := req.Execute(syscall.NETLINK_XFRM, nl.XFRM_MSG_NEWSA)
- if err != nil {
- return nil, err
- }
-
- var res []XfrmState
- for _, m := range msgs {
- msg := nl.DeserializeXfrmUsersaInfo(m)
-
- if family != FAMILY_ALL && family != int(msg.Family) {
- continue
- }
-
- var state XfrmState
-
- state.Dst = msg.Id.Daddr.ToIP()
- state.Src = msg.Saddr.ToIP()
- state.Proto = Proto(msg.Id.Proto)
- state.Mode = Mode(msg.Mode)
- state.Spi = int(nl.Swap32(msg.Id.Spi))
- state.Reqid = int(msg.Reqid)
- state.ReplayWindow = int(msg.ReplayWindow)
-
- attrs, err := nl.ParseRouteAttr(m[msg.Len():])
- if err != nil {
- return nil, err
- }
-
- for _, attr := range attrs {
- switch attr.Attr.Type {
- case nl.XFRMA_ALG_AUTH, nl.XFRMA_ALG_CRYPT:
- var resAlgo *XfrmStateAlgo
- if attr.Attr.Type == nl.XFRMA_ALG_AUTH {
- if state.Auth == nil {
- state.Auth = new(XfrmStateAlgo)
- }
- resAlgo = state.Auth
- } else {
- state.Crypt = new(XfrmStateAlgo)
- resAlgo = state.Crypt
- }
- algo := nl.DeserializeXfrmAlgo(attr.Value[:])
- (*resAlgo).Name = nl.BytesToString(algo.AlgName[:])
- (*resAlgo).Key = algo.AlgKey
- case nl.XFRMA_ALG_AUTH_TRUNC:
- if state.Auth == nil {
- state.Auth = new(XfrmStateAlgo)
- }
- algo := nl.DeserializeXfrmAlgoAuth(attr.Value[:])
- state.Auth.Name = nl.BytesToString(algo.AlgName[:])
- state.Auth.Key = algo.AlgKey
- state.Auth.TruncateLen = int(algo.AlgTruncLen)
- case nl.XFRMA_ENCAP:
- encap := nl.DeserializeXfrmEncapTmpl(attr.Value[:])
- state.Encap = new(XfrmStateEncap)
- state.Encap.Type = EncapType(encap.EncapType)
- state.Encap.SrcPort = int(nl.Swap16(encap.EncapSport))
- state.Encap.DstPort = int(nl.Swap16(encap.EncapDport))
- state.Encap.OriginalAddress = encap.EncapOa.ToIP()
- }
-
- }
- res = append(res, state)
- }
- return res, nil
-}
diff --git a/vendor/github.com/opencontainers/runc/Makefile b/vendor/github.com/opencontainers/runc/Makefile
index 5de10d0b..819bad09 100644
--- a/vendor/github.com/opencontainers/runc/Makefile
+++ b/vendor/github.com/opencontainers/runc/Makefile
@@ -1,57 +1,140 @@
-RUNC_IMAGE=runc_dev
-RUNC_TEST_IMAGE=runc_test
-PROJECT=github.com/opencontainers/runc
-TEST_DOCKERFILE=script/test_Dockerfile
-BUILDTAGS=seccomp
-RUNC_BUILD_PATH=/go/src/github.com/opencontainers/runc/runc
-RUNC_INSTANCE=runc_dev
-COMMIT=$(shell git rev-parse HEAD 2> /dev/null || true)
-RUNC_LINK=$(CURDIR)/Godeps/_workspace/src/github.com/opencontainers/runc
-export GOPATH:=$(CURDIR)/Godeps/_workspace:$(GOPATH)
+.PHONY: all shell dbuild man \
+ localtest localunittest localintegration \
+ test unittest integration
-.PHONY=dbuild
+SOURCES := $(shell find . 2>&1 | grep -E '.*\.(c|h|go)$$')
+PREFIX := $(DESTDIR)/usr/local
+BINDIR := $(PREFIX)/sbin
+GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null)
+GIT_BRANCH_CLEAN := $(shell echo $(GIT_BRANCH) | sed -e "s/[^[:alnum:]]/-/g")
+RUNC_IMAGE := runc_dev$(if $(GIT_BRANCH_CLEAN),:$(GIT_BRANCH_CLEAN))
+PROJECT := github.com/opencontainers/runc
+BUILDTAGS := seccomp
+COMMIT_NO := $(shell git rev-parse HEAD 2> /dev/null || true)
+COMMIT := $(if $(shell git status --porcelain --untracked-files=no),"${COMMIT_NO}-dirty","${COMMIT_NO}")
+RUNC_LINK := $(CURDIR)/Godeps/_workspace/src/github.com/opencontainers/runc
+export GOPATH := $(CURDIR)/Godeps/_workspace
-all:
-ifneq ($(RUNC_LINK), $(wildcard $(RUNC_LINK)))
+MAN_DIR := $(CURDIR)/man/man8
+MAN_PAGES = $(shell ls $(MAN_DIR)/*.8)
+MAN_PAGES_BASE = $(notdir $(MAN_PAGES))
+MAN_INSTALL_PATH := ${PREFIX}/share/man/man8/
+
+RELEASE_DIR := $(CURDIR)/release
+
+VERSION := ${shell cat ./VERSION}
+
+SHELL := $(shell command -v bash 2>/dev/null)
+
+.DEFAULT: runc
+
+runc: $(SOURCES) | $(RUNC_LINK)
+ go build -i -ldflags "-X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -tags "$(BUILDTAGS)" -o runc .
+
+all: runc recvtty
+
+recvtty: contrib/cmd/recvtty/recvtty
+
+contrib/cmd/recvtty/recvtty: $(SOURCES) | $(RUNC_LINK)
+ go build -i -ldflags "-X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -tags "$(BUILDTAGS)" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
+
+static: $(SOURCES) | $(RUNC_LINK)
+ CGO_ENABLED=1 go build -i -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -extldflags -static -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -o runc .
+ CGO_ENABLED=1 go build -i -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -extldflags -static -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
+
+release: $(RUNC_LINK) | $(RUNC_LINK)
+ @flag_list=(seccomp selinux apparmor static ambient); \
+ unset expression; \
+ for flag in "$${flag_list[@]}"; do \
+ expression+="' '{'',$${flag}}"; \
+ done; \
+ eval profile_list=("$$expression"); \
+ for profile in "$${profile_list[@]}"; do \
+ output=${RELEASE_DIR}/runc; \
+ for flag in $$profile; do \
+ output+=."$$flag"; \
+ done; \
+ tags="$$profile"; \
+ ldflags="-X main.gitCommit=${COMMIT} -X main.version=${VERSION}"; \
+ CGO_ENABLED=; \
+ [[ "$$profile" =~ static ]] && { \
+ tags="$${tags/static/static_build}"; \
+ tags+=" cgo"; \
+ ldflags+=" -w -extldflags -static"; \
+ CGO_ENABLED=1; \
+ }; \
+ echo "Building target: $$output"; \
+ rm -rf "${GOPATH}/pkg"; \
+ go build -i -ldflags "$$ldflags" -tags "$$tags" -o "$$output" .; \
+ done
+
+$(RUNC_LINK):
ln -sfn $(CURDIR) $(RUNC_LINK)
-endif
- go build -ldflags "-X main.gitCommit=${COMMIT}" -tags "$(BUILDTAGS)" -o runc .
-static:
- CGO_ENABLED=1 go build -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -extldflags -static -X main.gitCommit=${COMMIT}" -o runc .
+dbuild: runcimage
+ docker run --rm -v $(CURDIR):/go/src/$(PROJECT) --privileged $(RUNC_IMAGE) make clean all
lint:
go vet ./...
go fmt ./...
-runctestimage:
- docker build -t $(RUNC_TEST_IMAGE) -f $(TEST_DOCKERFILE) .
+man:
+ man/md2man-all.sh
-test: runctestimage
- docker run -e TESTFLAGS -ti --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) $(RUNC_TEST_IMAGE) make localtest
- tests/sniffTest
-
-localtest: all
- go test -tags "$(BUILDTAGS)" ${TESTFLAGS} -v ./...
-
-dbuild: runctestimage
+runcimage:
docker build -t $(RUNC_IMAGE) .
- docker create --name=$(RUNC_INSTANCE) $(RUNC_IMAGE)
- docker cp $(RUNC_INSTANCE):$(RUNC_BUILD_PATH) .
- docker rm $(RUNC_INSTANCE)
+
+test:
+ make unittest integration
+
+localtest:
+ make localunittest localintegration
+
+unittest: runcimage
+ docker run -e TESTFLAGS -t --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) $(RUNC_IMAGE) make localunittest
+
+localunittest: all
+ go test -timeout 3m -tags "$(BUILDTAGS)" ${TESTFLAGS} -v ./...
+
+integration: runcimage
+ docker run -e TESTFLAGS -t --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) $(RUNC_IMAGE) make localintegration
+
+localintegration: all
+ bats -t tests/integration${TESTFLAGS}
+
+shell: all
+ docker run -e TESTFLAGS -ti --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) $(RUNC_IMAGE) bash
install:
- install -D -m0755 runc /usr/local/sbin/runc
+ install -D -m0755 runc $(BINDIR)/runc
+
+install-bash:
+ install -D -m0644 contrib/completions/bash/runc $(PREFIX)/share/bash-completion/completions/runc
+
+install-man:
+ install -d -m 755 $(MAN_INSTALL_PATH)
+ install -m 644 $(MAN_PAGES) $(MAN_INSTALL_PATH)
uninstall:
- rm -f /usr/local/sbin/runc
+ rm -f $(BINDIR)/runc
+
+uninstall-bash:
+ rm -f $(PREFIX)/share/bash-completion/completions/runc
+
+uninstall-man:
+ rm -f $(addprefix $(MAN_INSTALL_PATH),$(MAN_PAGES_BASE))
clean:
rm -f runc
+ rm -f contrib/cmd/recvtty/recvtty
rm -f $(RUNC_LINK)
+ rm -rf $(GOPATH)/pkg
+ rm -rf $(RELEASE_DIR)
+ rm -rf $(MAN_DIR)
validate:
script/validate-gofmt
+ script/validate-shfmt
go vet ./...
ci: validate localtest
diff --git a/vendor/github.com/opencontainers/runc/README.md b/vendor/github.com/opencontainers/runc/README.md
index 1e6e503a..2212f4c5 100644
--- a/vendor/github.com/opencontainers/runc/README.md
+++ b/vendor/github.com/opencontainers/runc/README.md
@@ -1,144 +1,200 @@
-[![Build Status](https://jenkins.dockerproject.org/buildStatus/icon?job=runc Master)](https://jenkins.dockerproject.org/job/runc Master)
+# runc
-## runc
+[![Build Status](https://travis-ci.org/opencontainers/runc.svg?branch=master)](https://travis-ci.org/opencontainers/runc)
+[![Go Report Card](https://goreportcard.com/badge/github.com/opencontainers/runc)](https://goreportcard.com/report/github.com/opencontainers/runc)
+[![GoDoc](https://godoc.org/github.com/opencontainers/runc?status.svg)](https://godoc.org/github.com/opencontainers/runc)
-`runc` is a CLI tool for spawning and running containers according to the OCF specification.
+## Introduction
-## State of the project
+`runc` is a CLI tool for spawning and running containers according to the OCI specification.
-Currently `runc` is an implementation of the OCI specification. We are currently sprinting
-to have a v1 of the spec out. So the `runc` config format will be constantly changing until
-the spec is finalized. However, we encourage you to try out the tool and give feedback.
+## Releases
-### OCF
+`runc` depends on and tracks the [runtime-spec](https://github.com/opencontainers/runtime-spec) repository.
+We will try to make sure that `runc` and the OCI specification major versions stay in lockstep.
+This means that `runc` 1.0.0 should implement the 1.0 version of the specification.
-How does `runc` integrate with the Open Container Initiative Specification?
-`runc` depends on the types specified in the
-[specs](https://github.com/opencontainers/runtime-spec) repository. Whenever the
-specification is updated and ready to be versioned `runc` will update its dependency
-on the specs repository and support the update spec.
+You can find official releases of `runc` on the [release](https://github.com/opencontainers/runc/releases) page.
-### Building:
+### Security
-At the time of writing, runc only builds on the Linux platform.
+If you wish to report a security issue, please disclose the issue responsibly
+to security@opencontainers.org.
+
+## Building
+
+`runc` currently supports the Linux platform with various architecture support.
+It must be built with Go version 1.6 or higher in order for some features to function properly.
+
+In order to enable seccomp support you will need to install `libseccomp` on your platform.
+> e.g. `libseccomp-devel` for CentOS, or `libseccomp-dev` for Ubuntu
+
+Otherwise, if you do not want to build `runc` with seccomp support you can add `BUILDTAGS=""` when running make.
```bash
# create a 'github.com/opencontainers' in your GOPATH/src
cd github.com/opencontainers
git clone https://github.com/opencontainers/runc
cd runc
+
make
sudo make install
```
-In order to enable seccomp support you will need to install libseccomp on your platform.
-If you do not want to build `runc` with seccomp support you can add `BUILDTAGS=""` when running make.
+`runc` will be installed to `/usr/local/sbin/runc` on your system.
#### Build Tags
-`runc` supports optional build tags for compiling in support for various features.
+`runc` supports optional build tags for compiling support of various features.
+To add build tags to the make option the `BUILDTAGS` variable must be set.
+```bash
+make BUILDTAGS='seccomp apparmor'
+```
| Build Tag | Feature | Dependency |
|-----------|------------------------------------|-------------|
| seccomp | Syscall filtering | libseccomp |
| selinux | selinux process and mount labeling | |
| apparmor | apparmor profile support | libapparmor |
+| ambient | ambient capability support | kernel 4.3 |
-### Testing:
-You can run tests for runC by using command:
+### Running the test suite
+
+`runc` currently supports running its test suite via Docker.
+To run the suite just type `make test`.
```bash
-# make test
+make test
```
-Note that test cases are run in Docker container, so you need to install
-`docker` first. And test requires mounting cgroups inside container, it's
-done by docker now, so you need a docker version newer than 1.8.0-rc2.
+There are additional make targets for running the tests outside of a container but this is not recommended as the tests are written with the expectation that they can write and remove anywhere.
-You can also run specific test cases by:
+You can run a specific test case by setting the `TESTFLAGS` variable.
```bash
# make test TESTFLAGS="-run=SomeTestFunction"
```
-### Using:
+## Using runc
-To run a container with the id "test", execute `runc start` with the containers id as arg one
-in the bundle's root directory:
+### Creating an OCI Bundle
+
+In order to use runc you must have your container in the format of an OCI bundle.
+If you have Docker installed you can use its `export` method to acquire a root filesystem from an existing Docker container.
```bash
-runc start test
-/ $ ps
-PID USER COMMAND
-1 daemon sh
-5 daemon sh
-/ $
-```
+# create the top most bundle directory
+mkdir /mycontainer
+cd /mycontainer
-### OCI Container JSON Format:
-
-OCI container JSON format is based on OCI [specs](https://github.com/opencontainers/runtime-spec).
-You can generate JSON files by using `runc spec`.
-It assumes that the file-system is found in a directory called
-`rootfs` and there is a user with uid and gid of `0` defined within that file-system.
-
-### Examples:
-
-#### Using a Docker image (requires version 1.3 or later)
-
-To test using Docker's `busybox` image follow these steps:
-* Install `docker` and download the `busybox` image: `docker pull busybox`
-* Create a container from that image and export its contents to a tar file:
-`docker export $(docker create busybox) > busybox.tar`
-* Untar the contents to create your filesystem directory:
-```
+# create the rootfs directory
mkdir rootfs
-tar -C rootfs -xf busybox.tar
-```
-* Create `config.json` by using `runc spec`.
-* Execute `runc start` and you should be placed into a shell where you can run `ps`:
-```
-$ runc start test
-/ # ps
-PID USER COMMAND
- 1 root sh
- 9 root ps
+
+# export busybox via Docker into the rootfs directory
+docker export $(docker create busybox) | tar -C rootfs -xvf -
```
-#### Using runc with systemd
+After a root filesystem is populated you just generate a spec in the format of a `config.json` file inside your bundle.
+`runc` provides a `spec` command to generate a base template spec that you are then able to edit.
+To find features and documentation for fields in the spec please refer to the [specs](https://github.com/opencontainers/runtime-spec) repository.
-To use runc with systemd, you can create a unit file
-`/usr/lib/systemd/system/minecraft.service` as below (edit your
-own Description or WorkingDirectory or service name as you need).
+```bash
+runc spec
+```
-```service
+### Running Containers
+
+Assuming you have an OCI bundle from the previous step you can execute the container in two different ways.
+
+The first way is to use the convenience command `run` that will handle creating, starting, and deleting the container after it exits.
+
+```bash
+cd /mycontainer
+
+runc run mycontainerid
+```
+
+If you used the unmodified `runc spec` template this should give you a `sh` session inside the container.
+
+The second way to start a container is using the specs lifecycle operations.
+This gives you more power over how the container is created and managed while it is running.
+This will also launch the container in the background so you will have to edit the `config.json` to remove the `terminal` setting for the simple examples here.
+Your process field in the `config.json` should look like this below with `"terminal": false` and `"args": ["sleep", "5"]`.
+
+
+```json
+ "process": {
+ "terminal": false,
+ "user": {
+ "uid": 0,
+ "gid": 0
+ },
+ "args": [
+ "sleep", "5"
+ ],
+ "env": [
+ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
+ "TERM=xterm"
+ ],
+ "cwd": "/",
+ "capabilities": [
+ "CAP_AUDIT_WRITE",
+ "CAP_KILL",
+ "CAP_NET_BIND_SERVICE"
+ ],
+ "rlimits": [
+ {
+ "type": "RLIMIT_NOFILE",
+ "hard": 1024,
+ "soft": 1024
+ }
+ ],
+ "noNewPrivileges": true
+ },
+```
+
+Now we can go though the lifecycle operations in your shell.
+
+
+```bash
+cd /mycontainer
+
+runc create mycontainerid
+
+# view the container is created and in the "created" state
+runc list
+
+# start the process inside the container
+runc start mycontainerid
+
+# after 5 seconds view that the container has exited and is now in the stopped state
+runc list
+
+# now delete the container
+runc delete mycontainerid
+```
+
+This adds more complexity but allows higher level systems to manage runc and provides points in the containers creation to setup various settings after the container has created and/or before it is deleted.
+This is commonly used to setup the container's network stack after `create` but before `start` where the user's defined process will be running.
+
+#### Supervisors
+
+`runc` can be used with process supervisors and init systems to ensure that containers are restarted when they exit.
+An example systemd unit file looks something like this.
+
+```systemd
[Unit]
-Description=Minecraft Build Server
-Documentation=http://minecraft.net
-After=network.target
+Description=Start My Container
[Service]
-CPUQuota=200%
-MemoryLimit=1536M
-ExecStart=/usr/local/bin/runc start minecraft
-Restart=on-failure
-WorkingDirectory=/containers/minecraftbuild
+Type=forking
+ExecStart=/usr/local/sbin/runc run -d --pid-file /run/mycontainerid.pid mycontainerid
+ExecStopPost=/usr/local/sbin/runc delete mycontainerid
+WorkingDirectory=/mycontainer
+PIDFile=/run/mycontainerid.pid
[Install]
WantedBy=multi-user.target
```
-
-Make sure you have the bundle's root directory and JSON configs in
-your WorkingDirectory, then use systemd commands to start the service:
-
-```bash
-systemctl daemon-reload
-systemctl start minecraft.service
-```
-
-Note that if you use JSON configs by `runc spec`, you need to modify
-`config.json` and change `process.terminal` to false so runc won't
-create tty, because we can't set terminal from the stdin when using
-systemd service.
diff --git a/vendor/github.com/opencontainers/runc/VERSION b/vendor/github.com/opencontainers/runc/VERSION
new file mode 100644
index 00000000..2136ac91
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/VERSION
@@ -0,0 +1 @@
+1.0.0-rc2
diff --git a/vendor/github.com/opencontainers/runc/checkpoint.go b/vendor/github.com/opencontainers/runc/checkpoint.go
index 81de35a8..aefedb8e 100644
--- a/vendor/github.com/opencontainers/runc/checkpoint.go
+++ b/vendor/github.com/opencontainers/runc/checkpoint.go
@@ -6,9 +6,11 @@ import (
"fmt"
"strconv"
"strings"
+ "syscall"
- "github.com/codegangsta/cli"
"github.com/opencontainers/runc/libcontainer"
+ "github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/urfave/cli"
)
var checkpointCommand = cli.Command{
@@ -28,21 +30,36 @@ checkpointed.`,
cli.BoolFlag{Name: "shell-job", Usage: "allow shell jobs"},
cli.StringFlag{Name: "page-server", Value: "", Usage: "ADDRESS:PORT of the page server"},
cli.BoolFlag{Name: "file-locks", Usage: "handle file locks, for safety"},
- cli.StringFlag{Name: "manage-cgroups-mode", Value: "", Usage: "cgroups mode: 'soft' (default), 'full' and 'strict'."},
+ cli.StringFlag{Name: "manage-cgroups-mode", Value: "", Usage: "cgroups mode: 'soft' (default), 'full' and 'strict'"},
+ cli.StringSliceFlag{Name: "empty-ns", Usage: "create a namespace, but don't restore its properies"},
},
- Action: func(context *cli.Context) {
+ Action: func(context *cli.Context) error {
+ if err := checkArgs(context, 1, exactArgs); err != nil {
+ return err
+ }
container, err := getContainer(context)
if err != nil {
- fatal(err)
+ return err
+ }
+ status, err := container.Status()
+ if err != nil {
+ return err
+ }
+ if status == libcontainer.Created {
+ fatalf("Container cannot be checkpointed in created state")
}
defer destroy(container)
options := criuOptions(context)
// these are the mandatory criu options for a container
setPageServer(context, options)
setManageCgroupsMode(context, options)
- if err := container.Checkpoint(options); err != nil {
- fatal(err)
+ if err := setEmptyNsMask(context, options); err != nil {
+ return err
}
+ if err := container.Checkpoint(options); err != nil {
+ return err
+ }
+ return nil
},
}
@@ -87,3 +104,22 @@ func setManageCgroupsMode(context *cli.Context, options *libcontainer.CriuOpts)
}
}
}
+
+var namespaceMapping = map[specs.LinuxNamespaceType]int{
+ specs.NetworkNamespace: syscall.CLONE_NEWNET,
+}
+
+func setEmptyNsMask(context *cli.Context, options *libcontainer.CriuOpts) error {
+ var nsmask int
+
+ for _, ns := range context.StringSlice("empty-ns") {
+ f, exists := namespaceMapping[specs.LinuxNamespaceType(ns)]
+ if !exists {
+ return fmt.Errorf("namespace %q is not supported", ns)
+ }
+ nsmask |= f
+ }
+
+ options.EmptyNs = uint32(nsmask)
+ return nil
+}
diff --git a/vendor/github.com/opencontainers/runc/contrib/cmd/recvtty/recvtty.go b/vendor/github.com/opencontainers/runc/contrib/cmd/recvtty/recvtty.go
new file mode 100644
index 00000000..196b3283
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/contrib/cmd/recvtty/recvtty.go
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2016 SUSE LLC
+ *
+ * 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 main
+
+import (
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net"
+ "os"
+ "strings"
+
+ "github.com/opencontainers/runc/libcontainer"
+ "github.com/opencontainers/runc/libcontainer/utils"
+ "github.com/urfave/cli"
+)
+
+// version will be populated by the Makefile, read from
+// VERSION file of the source code.
+var version = ""
+
+// gitCommit will be the hash that the binary was built from
+// and will be populated by the Makefile
+var gitCommit = ""
+
+const (
+ usage = `Open Container Initiative contrib/cmd/recvtty
+
+recvtty is a reference implementation of a consumer of runC's --console-socket
+API. It has two main modes of operation:
+
+ * single: Only permit one terminal to be sent to the socket, which is
+ then hooked up to the stdio of the recvtty process. This is useful
+ for rudimentary shell management of a container.
+
+ * null: Permit as many terminals to be sent to the socket, but they
+ are read to /dev/null. This is used for testing, and imitates the
+ old runC API's --console=/dev/pts/ptmx hack which would allow for a
+ similar trick. This is probably not what you want to use, unless
+ you're doing something like our bats integration tests.
+
+To use recvtty, just specify a socket path at which you want to receive
+terminals:
+
+ $ recvtty [--mode ] socket.sock
+`
+)
+
+func bail(err error) {
+ fmt.Fprintf(os.Stderr, "[recvtty] fatal error: %v\n", err)
+ os.Exit(1)
+}
+
+func handleSingle(path string) error {
+ // Open a socket.
+ ln, err := net.Listen("unix", path)
+ if err != nil {
+ return err
+ }
+ defer ln.Close()
+
+ // We only accept a single connection, since we can only really have
+ // one reader for os.Stdin. Plus this is all a PoC.
+ conn, err := ln.Accept()
+ if err != nil {
+ return err
+ }
+ defer conn.Close()
+
+ // Close ln, to allow for other instances to take over.
+ ln.Close()
+
+ // Get the fd of the connection.
+ unixconn, ok := conn.(*net.UnixConn)
+ if !ok {
+ return fmt.Errorf("failed to cast to unixconn")
+ }
+
+ socket, err := unixconn.File()
+ if err != nil {
+ return err
+ }
+ defer socket.Close()
+
+ // Get the master file descriptor from runC.
+ master, err := utils.RecvFd(socket)
+ if err != nil {
+ return err
+ }
+
+ // Print the file descriptor tag.
+ ti, err := libcontainer.GetTerminalInfo(master.Name())
+ if err != nil {
+ return err
+ }
+ fmt.Printf("[recvtty] received masterfd: container '%s'\n", ti.ContainerID)
+
+ // Copy from our stdio to the master fd.
+ quitChan := make(chan struct{})
+ go func() {
+ io.Copy(os.Stdout, master)
+ quitChan <- struct{}{}
+ }()
+ go func() {
+ io.Copy(master, os.Stdin)
+ quitChan <- struct{}{}
+ }()
+
+ // Only close the master fd once we've stopped copying.
+ <-quitChan
+ master.Close()
+ return nil
+}
+
+func handleNull(path string) error {
+ // Open a socket.
+ ln, err := net.Listen("unix", path)
+ if err != nil {
+ return err
+ }
+ defer ln.Close()
+
+ // As opposed to handleSingle we accept as many connections as we get, but
+ // we don't interact with Stdin at all (and we copy stdout to /dev/null).
+ for {
+ conn, err := ln.Accept()
+ if err != nil {
+ return err
+ }
+ go func(conn net.Conn) {
+ // Don't leave references lying around.
+ defer conn.Close()
+
+ // Get the fd of the connection.
+ unixconn, ok := conn.(*net.UnixConn)
+ if !ok {
+ return
+ }
+
+ socket, err := unixconn.File()
+ if err != nil {
+ return
+ }
+ defer socket.Close()
+
+ // Get the master file descriptor from runC.
+ master, err := utils.RecvFd(socket)
+ if err != nil {
+ return
+ }
+
+ // Print the file descriptor tag.
+ ti, err := libcontainer.GetTerminalInfo(master.Name())
+ if err != nil {
+ bail(err)
+ }
+ fmt.Printf("[recvtty] received masterfd: container '%s'\n", ti.ContainerID)
+
+ // Just do a dumb copy to /dev/null.
+ devnull, err := os.OpenFile("/dev/null", os.O_RDWR, 0)
+ if err != nil {
+ // TODO: Handle this nicely.
+ return
+ }
+
+ io.Copy(devnull, master)
+ devnull.Close()
+ }(conn)
+ }
+}
+
+func main() {
+ app := cli.NewApp()
+ app.Name = "recvtty"
+ app.Usage = usage
+
+ // Set version to be the same as runC.
+ var v []string
+ if version != "" {
+ v = append(v, version)
+ }
+ if gitCommit != "" {
+ v = append(v, fmt.Sprintf("commit: %s", gitCommit))
+ }
+ app.Version = strings.Join(v, "\n")
+
+ // Set the flags.
+ app.Flags = []cli.Flag{
+ cli.StringFlag{
+ Name: "mode, m",
+ Value: "single",
+ Usage: "Mode of operation (single or null)",
+ },
+ cli.StringFlag{
+ Name: "pid-file",
+ Value: "",
+ Usage: "Path to write daemon process ID to",
+ },
+ }
+
+ app.Action = func(ctx *cli.Context) error {
+ args := ctx.Args()
+ if len(args) != 1 {
+ return fmt.Errorf("need to specify a single socket path")
+ }
+ path := ctx.Args()[0]
+
+ pidPath := ctx.String("pid-file")
+ if pidPath != "" {
+ pid := fmt.Sprintf("%d\n", os.Getpid())
+ if err := ioutil.WriteFile(pidPath, []byte(pid), 0644); err != nil {
+ return err
+ }
+ }
+
+ switch ctx.String("mode") {
+ case "single":
+ if err := handleSingle(path); err != nil {
+ return err
+ }
+ case "null":
+ if err := handleNull(path); err != nil {
+ return err
+ }
+ default:
+ return fmt.Errorf("need to select a valid mode: %s", ctx.String("mode"))
+ }
+ return nil
+ }
+ if err := app.Run(os.Args); err != nil {
+ bail(err)
+ }
+}
diff --git a/vendor/github.com/opencontainers/runc/contrib/completions/bash/runc b/vendor/github.com/opencontainers/runc/contrib/completions/bash/runc
new file mode 100644
index 00000000..0d6039df
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/contrib/completions/bash/runc
@@ -0,0 +1,805 @@
+#!/bin/bash
+#
+# bash completion file for runc command
+#
+# This script provides completion of:
+# - commands and their options
+# - filepaths
+#
+# To enable the completions either:
+# - place this file in /usr/share/bash-completion/completions
+# or
+# - copy this file to e.g. ~/.runc-completion.sh and add the line
+# below to your .bashrc after bash completion features are loaded
+# . ~/.runc-completion.sh
+#
+# Configuration:
+#
+
+# Note for developers:
+# Please arrange options sorted alphabetically by long name with the short
+# options immediately following their corresponding long form.
+# This order should be applied to lists, alternatives and code blocks.
+
+__runc_previous_extglob_setting=$(shopt -p extglob)
+shopt -s extglob
+
+__runc_list_all() {
+ COMPREPLY=($(compgen -W "$(runc list -q)" -- $cur))
+}
+
+__runc_pos_first_nonflag() {
+ local argument_flags=$1
+
+ local counter=$((${subcommand_pos:-${command_pos}} + 1))
+ while [ $counter -le $cword ]; do
+ if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then
+ ((counter++))
+ else
+ case "${words[$counter]}" in
+ -*) ;;
+ *)
+ break
+ ;;
+ esac
+ fi
+ ((counter++))
+ done
+
+ echo $counter
+}
+
+# Transforms a multiline list of strings into a single line string
+# with the words separated by "|".
+# This is used to prepare arguments to __runc_pos_first_nonflag().
+__runc_to_alternatives() {
+ local parts=($1)
+ local IFS='|'
+ echo "${parts[*]}"
+}
+
+# Transforms a multiline list of options into an extglob pattern
+# suitable for use in case statements.
+__runc_to_extglob() {
+ local extglob=$(__runc_to_alternatives "$1")
+ echo "@($extglob)"
+}
+
+# Subcommand processing.
+# Locates the first occurrence of any of the subcommands contained in the
+# first argument. In case of a match, calls the corresponding completion
+# function and returns 0.
+# If no match is found, 1 is returned. The calling function can then
+# continue processing its completion.
+#
+# TODO if the preceding command has options that accept arguments and an
+# argument is equal ot one of the subcommands, this is falsely detected as
+# a match.
+__runc_subcommands() {
+ local subcommands="$1"
+
+ local counter=$(($command_pos + 1))
+ while [ $counter -lt $cword ]; do
+ case "${words[$counter]}" in
+ $(__runc_to_extglob "$subcommands"))
+ subcommand_pos=$counter
+ local subcommand=${words[$counter]}
+ local completions_func=_runc_${command}_${subcommand}
+ declare -F $completions_func >/dev/null && $completions_func
+ return 0
+ ;;
+ esac
+ ((counter++))
+ done
+ return 1
+}
+
+# List all Signals
+__runc_list_signals() {
+ COMPREPLY=($(compgen -W "$(for i in $(kill -l | xargs); do echo $i; done | grep SIG)"))
+}
+
+# suppress trailing whitespace
+__runc_nospace() {
+ # compopt is not available in ancient bash versions
+ type compopt &>/dev/null && compopt -o nospace
+}
+
+# The list of capabilities is defined in types.go, ALL was added manually.
+__runc_complete_capabilities() {
+ COMPREPLY=($(compgen -W "
+ ALL
+ AUDIT_CONTROL
+ AUDIT_WRITE
+ AUDIT_READ
+ BLOCK_SUSPEND
+ CHOWN
+ DAC_OVERRIDE
+ DAC_READ_SEARCH
+ FOWNER
+ FSETID
+ IPC_LOCK
+ IPC_OWNER
+ KILL
+ LEASE
+ LINUX_IMMUTABLE
+ MAC_ADMIN
+ MAC_OVERRIDE
+ MKNOD
+ NET_ADMIN
+ NET_BIND_SERVICE
+ NET_BROADCAST
+ NET_RAW
+ SETFCAP
+ SETGID
+ SETPCAP
+ SETUID
+ SYS_ADMIN
+ SYS_BOOT
+ SYS_CHROOT
+ SYSLOG
+ SYS_MODULE
+ SYS_NICE
+ SYS_PACCT
+ SYS_PTRACE
+ SYS_RAWIO
+ SYS_RESOURCE
+ SYS_TIME
+ SYS_TTY_CONFIG
+ WAKE_ALARM
+ " -- "$cur"))
+}
+
+_runc_exec() {
+ local boolean_options="
+ --help
+ --no-new-privs
+ --tty, -t
+ --detach, -d
+ "
+
+ local options_with_args="
+ --console
+ --cwd
+ --env, -e
+ --user, -u
+ --process, -p
+ --pid-file
+ --process-label
+ --apparmor
+ --cap, -c
+ "
+
+ local all_options="$options_with_args $boolean_options"
+
+ case "$prev" in
+ --cap | -c)
+ __runc_complete_capabilities
+ return
+ ;;
+
+ --console | --cwd | --process | --apparmor)
+ case "$cur" in
+ *:*) ;; # TODO somehow do _filedir for stuff inside the image, if it's already specified (which is also somewhat difficult to determine)
+ '')
+ COMPREPLY=($(compgen -W '/' -- "$cur"))
+ __runc_nospace
+ ;;
+ /*)
+ _filedir
+ __runc_nospace
+ ;;
+ esac
+ return
+ ;;
+ --env | -e)
+ COMPREPLY=($(compgen -e -- "$cur"))
+ __runc_nospace
+ return
+ ;;
+ $(__runc_to_extglob "$options_with_args"))
+ return
+ ;;
+ esac
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$all_options" -- "$cur"))
+ ;;
+ *)
+ __runc_list_all
+ ;;
+ esac
+}
+
+# global options that may appear after the runc command
+_runc_runc() {
+ local boolean_options="
+ $global_boolean_options
+ --help
+ --version -v
+ --debug
+ "
+ local options_with_args="
+ --log
+ --log-format
+ --root
+ --criu
+ "
+
+ case "$prev" in
+ --log | --root | --criu)
+ case "$cur" in
+ *:*) ;; # TODO somehow do _filedir for stuff inside the image, if it's already specified (which is also somewhat difficult to determine)
+ '')
+ COMPREPLY=($(compgen -W '/' -- "$cur"))
+ __runc_nospace
+ ;;
+ *)
+ _filedir
+ __runc_nospace
+ ;;
+ esac
+ return
+ ;;
+
+ --log-format)
+ COMPREPLY=($(compgen -W 'text json' -- "$cur"))
+ return
+ ;;
+
+ $(__runc_to_extglob "$options_with_args"))
+ return
+ ;;
+ esac
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ *)
+ local counter=$(__runc_pos_first_nonflag $(__runc_to_extglob "$options_with_args"))
+ if [ $cword -eq $counter ]; then
+ COMPREPLY=($(compgen -W "${commands[*]} help" -- "$cur"))
+ fi
+ ;;
+ esac
+}
+
+_runc_pause() {
+ local boolean_options="
+ --help
+ -h
+ "
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ *)
+ __runc_list_all
+ ;;
+ esac
+}
+
+_runc_ps() {
+ local boolean_options="
+ --help
+ -h
+ "
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ *)
+ __runc_list_all
+ ;;
+ esac
+}
+
+_runc_delete() {
+ local boolean_options="
+ --help
+ -h
+ "
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ *)
+ __runc_list_all
+ ;;
+ esac
+}
+
+_runc_kill() {
+ local boolean_options="
+ --help
+ -h
+ --all
+ -a
+ "
+
+ case "$prev" in
+ "kill")
+ __runc_list_all
+ return
+ ;;
+ *)
+ __runc_list_signals
+ return
+ ;;
+ esac
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ *)
+ __runc_list_all
+ ;;
+ esac
+}
+
+_runc_events() {
+ local boolean_options="
+ --help
+ --stats
+ "
+
+ local options_with_args="
+ --interval
+ "
+
+ case "$prev" in
+ $(__runc_to_extglob "$options_with_args"))
+ return
+ ;;
+ esac
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ *)
+ __runc_list_all
+ ;;
+ esac
+}
+
+_runc_list() {
+ local boolean_options="
+ --help
+ --quiet
+ -q
+ "
+
+ local options_with_args="
+ --format
+ -f
+ "
+
+ case "$prev" in
+ --format | -f)
+ COMPREPLY=($(compgen -W 'text json' -- "$cur"))
+ return
+ ;;
+
+ $(__runc_to_extglob "$options_with_args"))
+ return
+ ;;
+ esac
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ *)
+ local counter=$(__runc_pos_first_nonflag $(__runc_to_extglob "$options_with_args"))
+ ;;
+ esac
+}
+
+_runc_spec() {
+ local boolean_options="
+ --help
+ "
+
+ local options_with_args="
+ --bundle
+ -b
+ "
+
+ case "$prev" in
+ --bundle | -b)
+ case "$cur" in
+ '')
+ COMPREPLY=($(compgen -W '/' -- "$cur"))
+ __runc_nospace
+ ;;
+ /*)
+ _filedir
+ __runc_nospace
+ ;;
+ esac
+ return
+ ;;
+
+ $(__runc_to_extglob "$options_with_args"))
+ return
+ ;;
+ esac
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ *)
+ local counter=$(__runc_pos_first_nonflag $(__runc_to_extglob "$options_with_args"))
+ ;;
+ esac
+}
+
+_runc_run() {
+ local boolean_options="
+ --help
+ --detatch
+ -d
+ --no-subreaper
+ --no-pivot
+ --no-new-keyring
+ "
+
+ local options_with_args="
+ --bundle
+ -b
+ --console
+ --pid-file
+ "
+
+ case "$prev" in
+ --bundle | -b | --console | --pid-file)
+ case "$cur" in
+ '')
+ COMPREPLY=($(compgen -W '/' -- "$cur"))
+ __runc_nospace
+ ;;
+ /*)
+ _filedir
+ __runc_nospace
+ ;;
+ esac
+ return
+ ;;
+
+ $(__runc_to_extglob "$options_with_args"))
+ return
+ ;;
+ esac
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ *)
+ __runc_list_all
+ ;;
+ esac
+}
+
+_runc_checkpoint() {
+ local boolean_options="
+ --help
+ -h
+ --leave-running
+ --tcp-established
+ --ext-unix-sk
+ --shell-job
+ --file-locks
+ "
+
+ local options_with_args="
+ --image-path
+ --work-path
+ --page-server
+ --manage-cgroups-mode
+ "
+
+ case "$prev" in
+ --page-server) ;;
+
+ --manage-cgroups-mode)
+ COMPREPLY=($(compgen -W "soft full strict" -- "$cur"))
+ return
+ ;;
+
+ --image-path | --work-path)
+ case "$cur" in
+ *:*) ;; # TODO somehow do _filedir for stuff inside the image, if it's already specified (which is also somewhat difficult to determine)
+ '')
+ COMPREPLY=($(compgen -W '/' -- "$cur"))
+ __runc_nospace
+ ;;
+ *)
+ _filedir
+ __runc_nospace
+ ;;
+ esac
+ return
+ ;;
+
+ $(__runc_to_extglob "$options_with_args"))
+ return
+ ;;
+ esac
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ *)
+ __runc_list_all
+ ;;
+ esac
+}
+_runc_create() {
+ local boolean_options="
+ --help
+ --no-pivot
+ --no-new-keyring
+ "
+
+ local options_with_args="
+ --bundle
+ -b
+ --console
+ --pid-file
+ "
+ case "$prev" in
+ --bundle | -b | --console | --pid-file)
+ case "$cur" in
+ '')
+ COMPREPLY=($(compgen -W '/' -- "$cur"))
+ __runc_nospace
+ ;;
+ /*)
+ _filedir
+ __runc_nospace
+ ;;
+ esac
+ return
+ ;;
+
+ $(__runc_to_extglob "$options_with_args"))
+ return
+ ;;
+ esac
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ *)
+ __runc_list_all
+ ;;
+ esac
+
+}
+
+_runc_help() {
+ local counter=$(__runc_pos_first_nonflag)
+ if [ $cword -eq $counter ]; then
+ COMPREPLY=($(compgen -W "${commands[*]}" -- "$cur"))
+ fi
+}
+
+_runc_restore() {
+ local boolean_options="
+ --help
+ --tcp-established
+ --ext-unix-sk
+ --shell-job
+ --file-locks
+ --detach
+ -d
+ --no-subreaper
+ --no-pivot
+ "
+
+ local options_with_args="
+ -b
+ --bundle
+ --image-path
+ --work-path
+ --manage-cgroups-mode
+ --pid-file
+ "
+
+ local all_options="$options_with_args $boolean_options"
+
+ case "$prev" in
+ --manage-cgroups-mode)
+ COMPREPLY=($(compgen -W "soft full strict" -- "$cur"))
+ return
+ ;;
+
+ --pid-file | --image-path | --work-path | --bundle | -b)
+ case "$cur" in
+ *:*) ;; # TODO somehow do _filedir for stuff inside the image, if it's already specified (which is also somewhat difficult to determine)
+ '')
+ COMPREPLY=($(compgen -W '/' -- "$cur"))
+ __runc_nospace
+ ;;
+ /*)
+ _filedir
+ __runc_nospace
+ ;;
+ esac
+ return
+ ;;
+
+ $(__runc_to_extglob "$options_with_args"))
+ return
+ ;;
+ esac
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$all_options" -- "$cur"))
+ ;;
+ *)
+ __runc_list_all
+ ;;
+ esac
+}
+
+_runc_resume() {
+ local boolean_options="
+ --help
+ -h
+ "
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ *)
+ __runc_list_all
+ ;;
+ esac
+}
+
+_runc_state() {
+ local boolean_options="
+ --help
+ -h
+ "
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ *)
+ __runc_list_all
+ ;;
+ esac
+}
+_runc_start() {
+ local boolean_options="
+ --help
+ -h
+ "
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ *)
+ __runc_list_all
+ ;;
+ esac
+}
+_runc_update() {
+ local boolean_options="
+ --help
+ "
+
+ local options_with_args="
+ --blkio-weight
+ --cpu-period
+ --cpu-quota
+ --cpu-rt-period
+ --cpu-rt-runtime
+ --cpu-share
+ --cpuset-cpus
+ --cpuset-mems
+ --kernel-memory
+ --kernel-memory-tcp
+ --memory
+ --memory-reservation
+ --memory-swap
+
+ "
+
+ case "$prev" in
+ $(__runc_to_extglob "$options_with_args"))
+ return
+ ;;
+ esac
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ *)
+ __runc_list_all
+ ;;
+ esac
+}
+
+_runc() {
+ local previous_extglob_setting=$(shopt -p extglob)
+ shopt -s extglob
+
+ local commands=(
+ checkpoint
+ create
+ delete
+ events
+ exec
+ init
+ kill
+ list
+ pause
+ ps
+ restore
+ resume
+ run
+ spec
+ start
+ state
+ update
+ help
+ h
+ )
+
+ # These options are valid as global options for all client commands
+ # and valid as command options for `runc daemon`
+ local global_boolean_options="
+ --help -h
+ --version -v
+ "
+
+ COMPREPLY=()
+ local cur prev words cword
+ _get_comp_words_by_ref -n : cur prev words cword
+
+ local command='runc' command_pos=0 subcommand_pos
+ local counter=1
+ while [ $counter -lt $cword ]; do
+ case "${words[$counter]}" in
+ -*) ;;
+ =)
+ ((counter++))
+ ;;
+ *)
+ command="${words[$counter]}"
+ command_pos=$counter
+ break
+ ;;
+ esac
+ ((counter++))
+ done
+
+ local completions_func=_runc_${command}
+ declare -F $completions_func >/dev/null && $completions_func
+
+ eval "$previous_extglob_setting"
+ return 0
+}
+
+eval "$__runc_previous_extglob_setting"
+unset __runc_previous_extglob_setting
+
+complete -F _runc runc
diff --git a/vendor/github.com/opencontainers/runc/create.go b/vendor/github.com/opencontainers/runc/create.go
new file mode 100644
index 00000000..403dab8d
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/create.go
@@ -0,0 +1,70 @@
+package main
+
+import (
+ "os"
+
+ "github.com/urfave/cli"
+)
+
+var createCommand = cli.Command{
+ Name: "create",
+ Usage: "create a container",
+ ArgsUsage: `
+
+Where "" is your name for the instance of the container that you
+are starting. The name you provide for the container instance must be unique on
+your host.`,
+ Description: `The create command creates an instance of a container for a bundle. The bundle
+is a directory with a specification file named "` + specConfig + `" and a root
+filesystem.
+
+The specification file includes an args parameter. The args parameter is used
+to specify command(s) that get run when the container is started. To change the
+command(s) that get executed on start, edit the args parameter of the spec. See
+"runc spec --help" for more explanation.`,
+ Flags: []cli.Flag{
+ cli.StringFlag{
+ Name: "bundle, b",
+ Value: "",
+ Usage: `path to the root of the bundle directory, defaults to the current directory`,
+ },
+ cli.StringFlag{
+ Name: "console-socket",
+ Value: "",
+ Usage: "path to an AF_UNIX socket which will receive a file descriptor referencing the master end of the console's pseudoterminal",
+ },
+ cli.StringFlag{
+ Name: "pid-file",
+ Value: "",
+ Usage: "specify the file to write the process id to",
+ },
+ cli.BoolFlag{
+ Name: "no-pivot",
+ Usage: "do not use pivot root to jail process inside rootfs. This should be used whenever the rootfs is on top of a ramdisk",
+ },
+ cli.BoolFlag{
+ Name: "no-new-keyring",
+ Usage: "do not create a new session keyring for the container. This will cause the container to inherit the calling processes session key",
+ },
+ },
+ Action: func(context *cli.Context) error {
+ if err := checkArgs(context, 1, exactArgs); err != nil {
+ return err
+ }
+ if err := revisePidFile(context); err != nil {
+ return err
+ }
+ spec, err := setupSpec(context)
+ if err != nil {
+ return err
+ }
+ status, err := startContainer(context, spec, true)
+ if err != nil {
+ return err
+ }
+ // exit with the container's exit status so any external supervisor is
+ // notified of the exit with the correct exit status.
+ os.Exit(status)
+ return nil
+ },
+}
diff --git a/vendor/github.com/opencontainers/runc/delete.go b/vendor/github.com/opencontainers/runc/delete.go
index 3468d106..21d7656a 100644
--- a/vendor/github.com/opencontainers/runc/delete.go
+++ b/vendor/github.com/opencontainers/runc/delete.go
@@ -1,38 +1,106 @@
+// +build !solaris
+
package main
import (
+ "fmt"
"os"
"path/filepath"
+ "syscall"
+ "time"
- "github.com/codegangsta/cli"
"github.com/opencontainers/runc/libcontainer"
+ "github.com/urfave/cli"
)
+func killContainer(container libcontainer.Container) error {
+ _ = container.Signal(syscall.SIGKILL, false)
+ for i := 0; i < 100; i++ {
+ time.Sleep(100 * time.Millisecond)
+ if err := container.Signal(syscall.Signal(0), false); err != nil {
+ destroy(container)
+ return nil
+ }
+ }
+ return fmt.Errorf("container init still running")
+}
+
var deleteCommand = cli.Command{
Name: "delete",
- Usage: "delete any resources held by the container often used with detached containers",
- ArgsUsage: `
+ Usage: "delete any resources held by one or more containers often used with detached containers",
+ ArgsUsage: ` [container-id...]
Where "" is the name for the instance of the container.
-
+
+EXAMPLE:
For example, if the container id is "ubuntu01" and runc list currently shows the
-status of "ubuntu01" as "destroyed" the following will delete resources held for
-"ubuntu01" removing "ubuntu01" from the runc list of containers:
-
+status of "ubuntu01" as "stopped" the following will delete resources held for
+"ubuntu01" removing "ubuntu01" from the runc list of containers:
+
# runc delete ubuntu01`,
- Action: func(context *cli.Context) {
- container, err := getContainer(context)
+ Flags: []cli.Flag{
+ cli.BoolFlag{
+ Name: "force, f",
+ Usage: "Forcibly deletes the container if it is still running (uses SIGKILL)",
+ },
+ },
+ Action: func(context *cli.Context) error {
+ if err := checkArgs(context, 1, minArgs); err != nil {
+ return err
+ }
+
+ hasError := false
+ factory, err := loadFactory(context)
if err != nil {
- if lerr, ok := err.(libcontainer.Error); ok && lerr.Code() == libcontainer.ContainerNotExists {
- // if there was an aborted start or something of the sort then the container's directory could exist but
- // libcontainer does not see it because the state.json file inside that directory was never created.
- path := filepath.Join(context.GlobalString("root"), context.Args().First())
- if err := os.RemoveAll(path); err == nil {
- return
+ return err
+ }
+ for _, id := range context.Args() {
+ container, err := factory.Load(id)
+ if err != nil {
+ if lerr, ok := err.(libcontainer.Error); ok && lerr.Code() == libcontainer.ContainerNotExists {
+ // if there was an aborted start or something of the sort then the container's directory could exist but
+ // libcontainer does not see it because the state.json file inside that directory was never created.
+ path := filepath.Join(context.GlobalString("root"), id)
+ if err = os.RemoveAll(path); err != nil {
+ fmt.Fprintf(os.Stderr, "remove %s: %v\n", path, err)
+ }
+ fmt.Fprintf(os.Stderr, "container %s does not exist\n", id)
+ }
+ hasError = true
+ continue
+ }
+ s, err := container.Status()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "status for %s: %v\n", id, err)
+ hasError = true
+ continue
+ }
+ switch s {
+ case libcontainer.Stopped:
+ destroy(container)
+ case libcontainer.Created:
+ err := killContainer(container)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "kill container %s: %v\n", id, err)
+ hasError = true
+ }
+ default:
+ if context.Bool("force") {
+ err := killContainer(container)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "kill container %s: %v\n", id, err)
+ hasError = true
+ }
+ } else {
+ fmt.Fprintf(os.Stderr, "cannot delete container %s that is not stopped: %s\n", id, s)
+ hasError = true
}
}
- fatal(err)
}
- destroy(container)
+
+ if hasError {
+ return fmt.Errorf("one or more of the container deletions failed")
+ }
+ return nil
},
}
diff --git a/vendor/github.com/opencontainers/runc/events.go b/vendor/github.com/opencontainers/runc/events.go
index 777ecea2..6c21e525 100644
--- a/vendor/github.com/opencontainers/runc/events.go
+++ b/vendor/github.com/opencontainers/runc/events.go
@@ -4,13 +4,15 @@ package main
import (
"encoding/json"
+ "fmt"
"os"
"sync"
"time"
"github.com/Sirupsen/logrus"
- "github.com/codegangsta/cli"
"github.com/opencontainers/runc/libcontainer"
+ "github.com/opencontainers/runc/libcontainer/cgroups"
+ "github.com/urfave/cli"
)
// event struct for encoding the event data to json.
@@ -20,9 +22,82 @@ type event struct {
Data interface{} `json:"data,omitempty"`
}
+// stats is the runc specific stats structure for stability when encoding and decoding stats.
+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"`
+}
+
var eventsCommand = cli.Command{
Name: "events",
- Usage: "display container events such as OOM notifications, cpu, memory, IO and network stats",
+ Usage: "display container events such as OOM notifications, cpu, memory, and IO usage statistics",
ArgsUsage: `
Where "" is the name for the instance of the container.`,
@@ -32,10 +107,24 @@ information is displayed once every 5 seconds.`,
cli.DurationFlag{Name: "interval", Value: 5 * time.Second, Usage: "set the stats collection interval"},
cli.BoolFlag{Name: "stats", Usage: "display the container's stats then exit"},
},
- Action: func(context *cli.Context) {
+ Action: func(context *cli.Context) error {
+ if err := checkArgs(context, 1, exactArgs); err != nil {
+ return err
+ }
container, err := getContainer(context)
if err != nil {
- fatal(err)
+ return err
+ }
+ duration := context.Duration("interval")
+ if duration <= 0 {
+ return fmt.Errorf("duration interval must be greater than 0")
+ }
+ status, err := container.Status()
+ if err != nil {
+ return err
+ }
+ if status == libcontainer.Stopped {
+ return fmt.Errorf("container with id %s is not running", container.ID())
}
var (
stats = make(chan *libcontainer.Stats, 1)
@@ -55,12 +144,12 @@ information is displayed once every 5 seconds.`,
if context.Bool("stats") {
s, err := container.Stats()
if err != nil {
- fatal(err)
+ return err
}
- events <- &event{Type: "stats", ID: container.ID(), Data: s}
+ events <- &event{Type: "stats", ID: container.ID(), Data: convertLibcontainerStats(s)}
close(events)
group.Wait()
- return
+ return nil
}
go func() {
for range time.Tick(context.Duration("interval")) {
@@ -74,7 +163,7 @@ information is displayed once every 5 seconds.`,
}()
n, err := container.NotifyOOM()
if err != nil {
- fatal(err)
+ return err
}
for {
select {
@@ -88,7 +177,7 @@ information is displayed once every 5 seconds.`,
n = nil
}
case s := <-stats:
- events <- &event{Type: "stats", ID: container.ID(), Data: s}
+ events <- &event{Type: "stats", ID: container.ID(), Data: convertLibcontainerStats(s)}
}
if n == nil {
close(events)
@@ -96,5 +185,76 @@ information is displayed once every 5 seconds.`,
}
}
group.Wait()
+ return nil
},
}
+
+func convertLibcontainerStats(ls *libcontainer.Stats) *stats {
+ cg := ls.CgroupStats
+ if cg == nil {
+ return nil
+ }
+ var s stats
+ s.Pids.Current = cg.PidsStats.Current
+ s.Pids.Limit = cg.PidsStats.Limit
+
+ s.CPU.Usage.Kernel = cg.CpuStats.CpuUsage.UsageInKernelmode
+ s.CPU.Usage.User = cg.CpuStats.CpuUsage.UsageInUsermode
+ s.CPU.Usage.Total = cg.CpuStats.CpuUsage.TotalUsage
+ s.CPU.Usage.Percpu = cg.CpuStats.CpuUsage.PercpuUsage
+ s.CPU.Throttling.Periods = cg.CpuStats.ThrottlingData.Periods
+ s.CPU.Throttling.ThrottledPeriods = cg.CpuStats.ThrottlingData.ThrottledPeriods
+ s.CPU.Throttling.ThrottledTime = cg.CpuStats.ThrottlingData.ThrottledTime
+
+ s.Memory.Cache = cg.MemoryStats.Cache
+ s.Memory.Kernel = convertMemoryEntry(cg.MemoryStats.KernelUsage)
+ s.Memory.KernelTCP = convertMemoryEntry(cg.MemoryStats.KernelTCPUsage)
+ s.Memory.Swap = convertMemoryEntry(cg.MemoryStats.SwapUsage)
+ s.Memory.Usage = convertMemoryEntry(cg.MemoryStats.Usage)
+ s.Memory.Raw = cg.MemoryStats.Stats
+
+ s.Blkio.IoServiceBytesRecursive = convertBlkioEntry(cg.BlkioStats.IoServiceBytesRecursive)
+ s.Blkio.IoServicedRecursive = convertBlkioEntry(cg.BlkioStats.IoServicedRecursive)
+ s.Blkio.IoQueuedRecursive = convertBlkioEntry(cg.BlkioStats.IoQueuedRecursive)
+ s.Blkio.IoServiceTimeRecursive = convertBlkioEntry(cg.BlkioStats.IoServiceTimeRecursive)
+ s.Blkio.IoWaitTimeRecursive = convertBlkioEntry(cg.BlkioStats.IoWaitTimeRecursive)
+ s.Blkio.IoMergedRecursive = convertBlkioEntry(cg.BlkioStats.IoMergedRecursive)
+ s.Blkio.IoTimeRecursive = convertBlkioEntry(cg.BlkioStats.IoTimeRecursive)
+ s.Blkio.SectorsRecursive = convertBlkioEntry(cg.BlkioStats.SectorsRecursive)
+
+ s.Hugetlb = make(map[string]hugetlb)
+ for k, v := range cg.HugetlbStats {
+ s.Hugetlb[k] = convertHugtlb(v)
+ }
+ return &s
+}
+
+func convertHugtlb(c cgroups.HugetlbStats) hugetlb {
+ return hugetlb{
+ Usage: c.Usage,
+ Max: c.MaxUsage,
+ Failcnt: c.Failcnt,
+ }
+}
+
+func convertMemoryEntry(c cgroups.MemoryData) memoryEntry {
+ return memoryEntry{
+ Limit: c.Limit,
+ Usage: c.Usage,
+ Max: c.MaxUsage,
+ Failcnt: c.Failcnt,
+ }
+}
+
+func convertBlkioEntry(c []cgroups.BlkioStatEntry) []blkioEntry {
+ var out []blkioEntry
+ for _, e := range c {
+ out = append(out, blkioEntry{
+ Major: e.Major,
+ Minor: e.Minor,
+ Op: e.Op,
+ Value: e.Value,
+ })
+ }
+ return out
+}
diff --git a/vendor/github.com/opencontainers/runc/exec.go b/vendor/github.com/opencontainers/runc/exec.go
index 76525886..d2512301 100644
--- a/vendor/github.com/opencontainers/runc/exec.go
+++ b/vendor/github.com/opencontainers/runc/exec.go
@@ -9,27 +9,30 @@ import (
"strconv"
"strings"
- "github.com/codegangsta/cli"
+ "github.com/opencontainers/runc/libcontainer"
"github.com/opencontainers/runc/libcontainer/utils"
"github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/urfave/cli"
)
var execCommand = cli.Command{
Name: "exec",
Usage: "execute new process inside the container",
- ArgsUsage: `
+ ArgsUsage: ` [command options] || -p process.json
Where "" is the name for the instance of the container and
-"" is the command to be executed in the container.
+"" is the command to be executed in the container.
+"" can't be empty unless a "-p" flag provided.
+EXAMPLE:
For example, if the container is configured to run the linux ps command the
following will output a list of processes running in the container:
-
+
# runc exec ps`,
Flags: []cli.Flag{
cli.StringFlag{
- Name: "console",
- Usage: "specify the pty slave path for use with the container",
+ Name: "console-socket",
+ Usage: "path to an AF_UNIX socket which will receive a file descriptor referencing the master end of the console's pseudoterminal",
},
cli.StringFlag{
Name: "cwd",
@@ -78,20 +81,28 @@ following will output a list of processes running in the container:
Usage: "add a capability to the bounding set for the process",
},
cli.BoolFlag{
- Name: "no-subreaper",
- Usage: "disable the use of the subreaper used to reap reparented processes",
+ Name: "no-subreaper",
+ Usage: "disable the use of the subreaper used to reap reparented processes",
+ Hidden: true,
},
},
- Action: func(context *cli.Context) {
+ Action: func(context *cli.Context) error {
+ if err := checkArgs(context, 1, minArgs); err != nil {
+ return err
+ }
if os.Geteuid() != 0 {
- fatalf("runc should be run as root")
+ return fmt.Errorf("runc should be run as root")
+ }
+ if err := revisePidFile(context); err != nil {
+ return err
}
status, err := execProcess(context)
- if err != nil {
- fatalf("exec failed: %v", err)
+ if err == nil {
+ os.Exit(status)
}
- os.Exit(status)
+ return fmt.Errorf("exec failed: %v", err)
},
+ SkipArgReorder: true,
}
func execProcess(context *cli.Context) (int, error) {
@@ -99,6 +110,17 @@ func execProcess(context *cli.Context) (int, error) {
if err != nil {
return -1, err
}
+ status, err := container.Status()
+ if err != nil {
+ return -1, err
+ }
+ if status == libcontainer.Stopped {
+ return -1, fmt.Errorf("cannot exec a container that has run and stopped")
+ }
+ path := context.String("process")
+ if path == "" && len(context.Args()) == 1 {
+ return -1, fmt.Errorf("process args cannot be empty")
+ }
detach := context.Bool("detach")
state, err := container.State()
if err != nil {
@@ -110,10 +132,10 @@ func execProcess(context *cli.Context) (int, error) {
return -1, err
}
r := &runner{
- enableSubreaper: !context.Bool("no-subreaper"),
+ enableSubreaper: false,
shouldDestroy: false,
container: container,
- console: context.String("console"),
+ consoleSocket: context.String("console-socket"),
detach: detach,
pidFile: context.String("pid-file"),
}
@@ -157,9 +179,8 @@ func getProcess(context *cli.Context, bundle string) (*specs.Process, error) {
p.Capabilities = caps
}
// append the passed env variables
- for _, e := range context.StringSlice("env") {
- p.Env = append(p.Env, e)
- }
+ p.Env = append(p.Env, context.StringSlice("env")...)
+
// set the tty
if context.IsSet("tty") {
p.Terminal = context.Bool("tty")
diff --git a/vendor/github.com/opencontainers/runc/kill.go b/vendor/github.com/opencontainers/runc/kill.go
index 3da8aaf6..f80c4db7 100644
--- a/vendor/github.com/opencontainers/runc/kill.go
+++ b/vendor/github.com/opencontainers/runc/kill.go
@@ -8,7 +8,7 @@ import (
"strings"
"syscall"
- "github.com/codegangsta/cli"
+ "github.com/urfave/cli"
)
var signalMap = map[string]syscall.Signal{
@@ -52,19 +52,32 @@ var signalMap = map[string]syscall.Signal{
var killCommand = cli.Command{
Name: "kill",
Usage: "kill sends the specified signal (default: SIGTERM) to the container's init process",
- ArgsUsage: `
+ ArgsUsage: ` [signal]
Where "" is the name for the instance of the container and
-"" is the signal to be sent to the init process.
-
+"[signal]" is the signal to be sent to the init process.
+
+EXAMPLE:
For example, if the container id is "ubuntu01" the following will send a "KILL"
signal to the init process of the "ubuntu01" container:
# runc kill ubuntu01 KILL`,
- Action: func(context *cli.Context) {
+ Flags: []cli.Flag{
+ cli.BoolFlag{
+ Name: "all, a",
+ Usage: "send the specified signal to all processes inside the container",
+ },
+ },
+ Action: func(context *cli.Context) error {
+ if err := checkArgs(context, 1, minArgs); err != nil {
+ return err
+ }
+ if err := checkArgs(context, 2, maxArgs); err != nil {
+ return err
+ }
container, err := getContainer(context)
if err != nil {
- fatal(err)
+ return err
}
sigstr := context.Args().Get(1)
@@ -74,19 +87,25 @@ signal to the init process of the "ubuntu01" container:
signal, err := parseSignal(sigstr)
if err != nil {
- fatal(err)
+ return err
}
-
- if err := container.Signal(signal); err != nil {
- fatal(err)
+ if err := container.Signal(signal, context.Bool("all")); err != nil {
+ return err
}
+ return nil
},
}
func parseSignal(rawSignal string) (syscall.Signal, error) {
s, err := strconv.Atoi(rawSignal)
if err == nil {
- return syscall.Signal(s), nil
+ sig := syscall.Signal(s)
+ for _, msig := range signalMap {
+ if sig == msig {
+ return sig, nil
+ }
+ }
+ return -1, fmt.Errorf("unknown signal %q", rawSignal)
}
signal, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")]
if !ok {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/README.md b/vendor/github.com/opencontainers/runc/libcontainer/README.md
index 61496946..d2a7d788 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/README.md
+++ b/vendor/github.com/opencontainers/runc/libcontainer/README.md
@@ -1,3 +1,7 @@
+# libcontainer
+
+[![GoDoc](https://godoc.org/github.com/opencontainers/runc/libcontainer?status.svg)](https://godoc.org/github.com/opencontainers/runc/libcontainer)
+
Libcontainer provides a native Go implementation for creating containers
with namespaces, cgroups, capabilities, and filesystem access controls.
It allows you to manage the lifecycle of the container performing additional operations
@@ -16,7 +20,14 @@ the current binary (/proc/self/exe) to be executed as the init process, and use
arg "init", we call the first step process "bootstrap", so you always need a "init"
function as the entry of "bootstrap".
+In addition to the go init function the early stage bootstrap is handled by importing
+[nsenter](https://github.com/opencontainers/runc/blob/master/libcontainer/nsenter/README.md).
+
```go
+import (
+ _ "github.com/opencontainers/runc/libcontainer/nsenter"
+)
+
func init() {
if len(os.Args) > 1 && os.Args[1] == "init" {
runtime.GOMAXPROCS(1)
@@ -77,12 +88,13 @@ config := &configs.Config{
Parent: "system",
Resources: &configs.Resources{
MemorySwappiness: nil,
- AllowAllDevices: false,
+ AllowAllDevices: nil,
AllowedDevices: configs.DefaultAllowedDevices,
},
},
MaskPaths: []string{
"/proc/kcore",
+ "/sys/firmware",
},
ReadonlyPaths: []string{
"/proc/sys", "/proc/sysrq-trigger", "/proc/irq", "/proc/bus",
@@ -184,10 +196,10 @@ process := &libcontainer.Process{
Stderr: os.Stderr,
}
-err := container.Start(process)
+err := container.Run(process)
if err != nil {
- logrus.Fatal(err)
container.Destroy()
+ logrus.Fatal(err)
return
}
@@ -219,6 +231,15 @@ container.Resume()
// send signal to container's init process.
container.Signal(signal)
+
+// update container resource constraints.
+container.Set(config)
+
+// get current status of the container.
+status, err := container.Status()
+
+// get current container's state information.
+state, err := container.State()
```
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/SPEC.md b/vendor/github.com/opencontainers/runc/libcontainer/SPEC.md
index 221545c0..e5894c64 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/SPEC.md
+++ b/vendor/github.com/opencontainers/runc/libcontainer/SPEC.md
@@ -71,7 +71,6 @@ that are required for executing a container's process.
| /dev/tty | 0666 | rwm |
| /dev/random | 0666 | rwm |
| /dev/urandom | 0666 | rwm |
-| /dev/fuse | 0666 | rwm |
**ptmx**
@@ -90,7 +89,7 @@ in tmpfs.
After `/dev/null` has been setup we check for any external links between
the container's io, STDIN, STDOUT, STDERR. If the container's io is pointing
-to `/dev/null` outside the container we close and `dup2` the the `/dev/null`
+to `/dev/null` outside the container we close and `dup2` the `/dev/null`
that is local to the container's rootfs.
@@ -297,7 +296,7 @@ a container.
| -------------- | ------------------------------------------------------------------ |
| Get processes | Return all the pids for processes running inside a container |
| Get Stats | Return resource statistics for the container as a whole |
-| Wait | Wait waits on the container's init process ( pid 1 ) |
+| Wait | Waits on the container's init process ( pid 1 ) |
| Wait Process | Wait on any of the container's processes returning the exit status |
| Destroy | Kill the container's init process and remove any filesystem state |
| Signal | Send a signal to the container's init process |
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go
index 22c17f52..82ed1a68 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go
@@ -7,6 +7,7 @@ package apparmor
// #include
import "C"
import (
+ "fmt"
"io/ioutil"
"os"
"unsafe"
@@ -32,7 +33,7 @@ func ApplyProfile(name string) error {
cName := C.CString(name)
defer C.free(unsafe.Pointer(cName))
if _, err := C.aa_change_onexec(cName); err != nil {
- return err
+ return fmt.Errorf("apparmor failed to apply profile: %s", err)
}
return nil
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/capabilities_ambient.go b/vendor/github.com/opencontainers/runc/libcontainer/capabilities_ambient.go
new file mode 100644
index 00000000..50da2832
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/capabilities_ambient.go
@@ -0,0 +1,7 @@
+// +build linux,ambient
+
+package libcontainer
+
+import "github.com/syndtr/gocapability/capability"
+
+const allCapabilityTypes = capability.CAPS | capability.BOUNDS | capability.AMBS
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/capabilities_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/capabilities_linux.go
index 4eda56d1..31fd0dcf 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/capabilities_linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/capabilities_linux.go
@@ -10,8 +10,6 @@ import (
"github.com/syndtr/gocapability/capability"
)
-const allCapabilityTypes = capability.CAPS | capability.BOUNDS
-
var capabilityMap map[string]capability.Cap
func init() {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/capabilities_noambient.go b/vendor/github.com/opencontainers/runc/libcontainer/capabilities_noambient.go
new file mode 100644
index 00000000..752c4e51
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/capabilities_noambient.go
@@ -0,0 +1,7 @@
+// +build !ambient,linux
+
+package libcontainer
+
+import "github.com/syndtr/gocapability/capability"
+
+const allCapabilityTypes = capability.CAPS | capability.BOUNDS
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/cgroups.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/cgroups.go
index 274ab47d..25ff5158 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/cgroups.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/cgroups.go
@@ -27,9 +27,9 @@ type Manager interface {
// Destroys the cgroup set
Destroy() error
- // NewCgroupManager() and LoadCgroupManager() require following attributes:
+ // The option func SystemdCgroups() and Cgroupfs() require following attributes:
// Paths map[string]string
- // Cgroups *cgroups.Cgroup
+ // Cgroups *configs.Cgroup
// Paths maps cgroup subsystem to path at which it is mounted.
// Cgroups specifies specific cgroup settings for the various subsystems
@@ -37,7 +37,7 @@ type Manager interface {
// restore the object later.
GetPaths() map[string]string
- // Set the cgroup as configured.
+ // Sets the cgroup as configured.
Set(container *configs.Config) error
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go
index 114f002e..3507026e 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go
@@ -9,7 +9,6 @@ import (
"io/ioutil"
"os"
"path/filepath"
- "strconv"
"sync"
"github.com/opencontainers/runc/libcontainer/cgroups"
@@ -33,7 +32,6 @@ var (
&FreezerGroup{},
&NameGroup{GroupName: "name=systemd", Join: true},
}
- CgroupProcesses = "cgroup.procs"
HugePageSizes, _ = cgroups.GetHugePageSize()
)
@@ -106,6 +104,8 @@ func (m *Manager) Apply(pid int) (err error) {
if m.Cgroups == nil {
return nil
}
+ m.mu.Lock()
+ defer m.mu.Unlock()
var c = m.Cgroups
@@ -114,8 +114,8 @@ func (m *Manager) Apply(pid int) (err error) {
return err
}
+ m.Paths = make(map[string]string)
if c.Paths != nil {
- paths := make(map[string]string)
for name, path := range c.Paths {
_, err := d.path(name)
if err != nil {
@@ -124,32 +124,30 @@ func (m *Manager) Apply(pid int) (err error) {
}
return err
}
- paths[name] = path
+ m.Paths[name] = path
}
- m.Paths = paths
return cgroups.EnterPid(m.Paths, pid)
}
- m.mu.Lock()
- defer m.mu.Unlock()
- paths := make(map[string]string)
for _, sys := range subsystems {
- if err := sys.Apply(d); err != nil {
- return err
- }
// TODO: Apply should, ideally, be reentrant or be broken up into a separate
// create and join phase so that the cgroup hierarchy for a container can be
// created then join consists of writing the process pids to cgroup.procs
p, err := d.path(sys.Name())
if err != nil {
- if cgroups.IsNotFound(err) {
+ // The non-presence of the devices subsystem is
+ // considered fatal for security reasons.
+ if cgroups.IsNotFound(err) && sys.Name() != "devices" {
continue
}
return err
}
- paths[sys.Name()] = p
+ m.Paths[sys.Name()] = p
+
+ if err := sys.Apply(d); err != nil {
+ return err
+ }
}
- m.Paths = paths
return nil
}
@@ -190,18 +188,15 @@ func (m *Manager) GetStats() (*cgroups.Stats, error) {
}
func (m *Manager) Set(container *configs.Config) error {
- for _, sys := range subsystems {
- // Generate fake cgroup data.
- d, err := getCgroupData(container.Cgroups, -1)
- if err != nil {
- return err
- }
- // Get the path, but don't error out if the cgroup wasn't found.
- path, err := d.path(sys.Name())
- if err != nil && !cgroups.IsNotFound(err) {
- return err
- }
+ // If Paths are set, then we are just joining cgroups paths
+ // and there is no need to set any values.
+ if m.Cgroups.Paths != nil {
+ return nil
+ }
+ paths := m.GetPaths()
+ for _, sys := range subsystems {
+ path := paths[sys.Name()]
if err := sys.Set(path, container.Cgroups); err != nil {
return err
}
@@ -218,14 +213,8 @@ func (m *Manager) Set(container *configs.Config) error {
// Freeze toggles the container's freezer cgroup depending on the state
// provided
func (m *Manager) Freeze(state configs.FreezerState) error {
- d, err := getCgroupData(m.Cgroups, 0)
- if err != nil {
- return err
- }
- dir, err := d.path("freezer")
- if err != nil {
- return err
- }
+ paths := m.GetPaths()
+ dir := paths["freezer"]
prevState := m.Cgroups.Resources.Freezer
m.Cgroups.Resources.Freezer = state
freezer, err := subsystems.Get("freezer")
@@ -241,28 +230,13 @@ func (m *Manager) Freeze(state configs.FreezerState) error {
}
func (m *Manager) GetPids() ([]int, error) {
- dir, err := getCgroupPath(m.Cgroups)
- if err != nil {
- return nil, err
- }
- return cgroups.GetPids(dir)
+ paths := m.GetPaths()
+ return cgroups.GetPids(paths["devices"])
}
func (m *Manager) GetAllPids() ([]int, error) {
- dir, err := getCgroupPath(m.Cgroups)
- if err != nil {
- return nil, err
- }
- return cgroups.GetAllPids(dir)
-}
-
-func getCgroupPath(c *configs.Cgroup) (string, error) {
- d, err := getCgroupData(c, 0)
- if err != nil {
- return "", err
- }
-
- return d.path("devices")
+ paths := m.GetPaths()
+ return cgroups.GetAllPids(paths["devices"])
}
func getCgroupData(c *configs.Cgroup, pid int) (*cgroupData, error) {
@@ -319,7 +293,7 @@ func (raw *cgroupData) path(subsystem string) (string, error) {
// If the cgroup name/path is absolute do not look relative to the cgroup of the init process.
if filepath.IsAbs(raw.innerPath) {
- // Sometimes subsystems can be mounted togethger as 'cpu,cpuacct'.
+ // Sometimes subsystems can be mounted together as 'cpu,cpuacct'.
return filepath.Join(raw.root, filepath.Base(mnt), raw.innerPath), nil
}
@@ -339,7 +313,7 @@ func (raw *cgroupData) join(subsystem string) (string, error) {
if err := os.MkdirAll(path, 0755); err != nil {
return "", err
}
- if err := writeFile(path, CgroupProcesses, strconv.Itoa(raw.pid)); err != nil {
+ if err := cgroups.WriteCgroupProc(path, raw.pid); err != nil {
return "", err
}
return path, nil
@@ -349,7 +323,7 @@ func writeFile(dir, file, data string) error {
// Normally dir should not be empty, one case is that cgroup subsystem
// is not mounted, we will get empty dir, and we want it fail here.
if dir == "" {
- return fmt.Errorf("no such directory for %s.", file)
+ return fmt.Errorf("no such directory for %s", file)
}
if err := ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700); err != nil {
return fmt.Errorf("failed to write %v to %v: %v", data, file, err)
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go
index a4ef28a6..7cd506a8 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go
@@ -22,10 +22,48 @@ func (s *CpuGroup) Name() string {
func (s *CpuGroup) Apply(d *cgroupData) error {
// We always want to join the cpu group, to allow fair cpu scheduling
// on a container basis
- _, err := d.join("cpu")
+ path, err := d.path("cpu")
if err != nil && !cgroups.IsNotFound(err) {
return err
}
+ return s.ApplyDir(path, d.config, d.pid)
+}
+
+func (s *CpuGroup) ApplyDir(path string, cgroup *configs.Cgroup, pid int) error {
+ // This might happen if we have no cpu cgroup mounted.
+ // Just do nothing and don't fail.
+ if path == "" {
+ return nil
+ }
+ if err := os.MkdirAll(path, 0755); err != nil {
+ return err
+ }
+ // We should set the real-Time group scheduling settings before moving
+ // in the process because if the process is already in SCHED_RR mode
+ // and no RT bandwidth is set, adding it will fail.
+ if err := s.SetRtSched(path, cgroup); err != nil {
+ return err
+ }
+ // because we are not using d.join we need to place the pid into the procs file
+ // unlike the other subsystems
+ if err := cgroups.WriteCgroupProc(path, pid); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (s *CpuGroup) SetRtSched(path string, cgroup *configs.Cgroup) error {
+ if cgroup.Resources.CpuRtPeriod != 0 {
+ if err := writeFile(path, "cpu.rt_period_us", strconv.FormatInt(cgroup.Resources.CpuRtPeriod, 10)); err != nil {
+ return err
+ }
+ }
+ if cgroup.Resources.CpuRtRuntime != 0 {
+ if err := writeFile(path, "cpu.rt_runtime_us", strconv.FormatInt(cgroup.Resources.CpuRtRuntime, 10)); err != nil {
+ return err
+ }
+ }
return nil
}
@@ -45,15 +83,8 @@ func (s *CpuGroup) Set(path string, cgroup *configs.Cgroup) error {
return err
}
}
- if cgroup.Resources.CpuRtPeriod != 0 {
- if err := writeFile(path, "cpu.rt_period_us", strconv.FormatInt(cgroup.Resources.CpuRtPeriod, 10)); err != nil {
- return err
- }
- }
- if cgroup.Resources.CpuRtRuntime != 0 {
- if err := writeFile(path, "cpu.rt_runtime_us", strconv.FormatInt(cgroup.Resources.CpuRtRuntime, 10)); err != nil {
- return err
- }
+ if err := s.SetRtSched(path, cgroup); err != nil {
+ return err
}
return nil
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu_test.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu_test.go
index 554fd5e8..6369c91a 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu_test.go
@@ -106,13 +106,13 @@ func TestCpuStats(t *testing.T) {
defer helper.cleanup()
const (
- kNrPeriods = 2000
- kNrThrottled = 200
- kThrottledTime = uint64(18446744073709551615)
+ nrPeriods = 2000
+ nrThrottled = 200
+ throttledTime = uint64(18446744073709551615)
)
cpuStatContent := fmt.Sprintf("nr_periods %d\n nr_throttled %d\n throttled_time %d\n",
- kNrPeriods, kNrThrottled, kThrottledTime)
+ nrPeriods, nrThrottled, throttledTime)
helper.writeFileContents(map[string]string{
"cpu.stat": cpuStatContent,
})
@@ -125,9 +125,9 @@ func TestCpuStats(t *testing.T) {
}
expectedStats := cgroups.ThrottlingData{
- Periods: kNrPeriods,
- ThrottledPeriods: kNrThrottled,
- ThrottledTime: kThrottledTime}
+ Periods: nrPeriods,
+ ThrottledPeriods: nrThrottled,
+ ThrottledTime: throttledTime}
expectThrottlingDataEquals(t, expectedStats, actualStats.CpuStats.ThrottlingData)
}
@@ -161,3 +161,49 @@ func TestInvalidCpuStat(t *testing.T) {
t.Fatal("Expected failed stat parsing.")
}
}
+
+func TestCpuSetRtSchedAtApply(t *testing.T) {
+ helper := NewCgroupTestUtil("cpu", t)
+ defer helper.cleanup()
+
+ const (
+ rtRuntimeBefore = 0
+ rtRuntimeAfter = 5000
+ rtPeriodBefore = 0
+ rtPeriodAfter = 7000
+ )
+
+ helper.writeFileContents(map[string]string{
+ "cpu.rt_runtime_us": strconv.Itoa(rtRuntimeBefore),
+ "cpu.rt_period_us": strconv.Itoa(rtPeriodBefore),
+ })
+
+ helper.CgroupData.config.Resources.CpuRtRuntime = rtRuntimeAfter
+ helper.CgroupData.config.Resources.CpuRtPeriod = rtPeriodAfter
+ cpu := &CpuGroup{}
+ if err := cpu.ApplyDir(helper.CgroupPath, helper.CgroupData.config, 1234); err != nil {
+ t.Fatal(err)
+ }
+
+ rtRuntime, err := getCgroupParamUint(helper.CgroupPath, "cpu.rt_runtime_us")
+ if err != nil {
+ t.Fatalf("Failed to parse cpu.rt_runtime_us - %s", err)
+ }
+ if rtRuntime != rtRuntimeAfter {
+ t.Fatal("Got the wrong value, set cpu.rt_runtime_us failed.")
+ }
+ rtPeriod, err := getCgroupParamUint(helper.CgroupPath, "cpu.rt_period_us")
+ if err != nil {
+ t.Fatalf("Failed to parse cpu.rt_period_us - %s", err)
+ }
+ if rtPeriod != rtPeriodAfter {
+ t.Fatal("Got the wrong value, set cpu.rt_period_us failed.")
+ }
+ pid, err := getCgroupParamUint(helper.CgroupPath, "cgroup.procs")
+ if err != nil {
+ t.Fatalf("Failed to parse cgroup.procs - %s", err)
+ }
+ if pid != 1234 {
+ t.Fatal("Got the wrong value, set cgroup.procs failed.")
+ }
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go
index cbe62bd9..918b9a30 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go
@@ -8,7 +8,6 @@ import (
"io/ioutil"
"os"
"path/filepath"
- "strconv"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
@@ -62,12 +61,29 @@ func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) erro
if err != nil {
return err
}
- if err := s.ensureParent(dir, root); err != nil {
+ // 'ensureParent' start with parent because we don't want to
+ // explicitly inherit from parent, it could conflict with
+ // 'cpuset.cpu_exclusive'.
+ if err := s.ensureParent(filepath.Dir(dir), root); err != nil {
return err
}
+ if err := os.MkdirAll(dir, 0755); err != nil {
+ return err
+ }
+ // We didn't inherit cpuset configs from parent, but we have
+ // to ensure cpuset configs are set before moving task into the
+ // cgroup.
+ // The logic is, if user specified cpuset configs, use these
+ // specified configs, otherwise, inherit from parent. This makes
+ // cpuset configs work correctly with 'cpuset.cpu_exclusive', and
+ // keep backward compatbility.
+ if err := s.ensureCpusAndMems(dir, cgroup); err != nil {
+ return err
+ }
+
// because we are not using d.join we need to place the pid into the procs file
// unlike the other subsystems
- if err := writeFile(dir, "cgroup.procs", strconv.Itoa(pid)); err != nil {
+ if err := cgroups.WriteCgroupProc(dir, pid); err != nil {
return err
}
@@ -137,3 +153,10 @@ func (s *CpusetGroup) copyIfNeeded(current, parent string) error {
func (s *CpusetGroup) isEmpty(b []byte) bool {
return len(bytes.Trim(b, "\n")) == 0
}
+
+func (s *CpusetGroup) ensureCpusAndMems(path string, cgroup *configs.Cgroup) error {
+ if err := s.Set(path, cgroup); err != nil {
+ return err
+ }
+ return s.copyIfNeeded(path, filepath.Dir(path))
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go
index 5f783310..0ac5b4ed 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go
@@ -43,21 +43,23 @@ func (s *DevicesGroup) Set(path string, cgroup *configs.Cgroup) error {
}
return nil
}
- if !cgroup.Resources.AllowAllDevices {
- if err := writeFile(path, "devices.deny", "a"); err != nil {
- return err
- }
-
- for _, dev := range cgroup.Resources.AllowedDevices {
- if err := writeFile(path, "devices.allow", dev.CgroupString()); err != nil {
+ if cgroup.Resources.AllowAllDevices != nil {
+ if *cgroup.Resources.AllowAllDevices == false {
+ if err := writeFile(path, "devices.deny", "a"); err != nil {
return err
}
- }
- return nil
- }
- if err := writeFile(path, "devices.allow", "a"); err != nil {
- return err
+ for _, dev := range cgroup.Resources.AllowedDevices {
+ if err := writeFile(path, "devices.allow", dev.CgroupString()); err != nil {
+ return err
+ }
+ }
+ return nil
+ }
+
+ if err := writeFile(path, "devices.allow", "a"); err != nil {
+ return err
+ }
}
for _, dev := range cgroup.Resources.DeniedDevices {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices_test.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices_test.go
index ee44084e..fc635b99 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices_test.go
@@ -40,8 +40,8 @@ func TestDevicesSetAllow(t *testing.T) {
helper.writeFileContents(map[string]string{
"devices.deny": "a",
})
-
- helper.CgroupData.config.Resources.AllowAllDevices = false
+ allowAllDevices := false
+ helper.CgroupData.config.Resources.AllowAllDevices = &allowAllDevices
helper.CgroupData.config.Resources.AllowedDevices = allowedDevices
devices := &DevicesGroup{}
if err := devices.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
@@ -56,6 +56,19 @@ func TestDevicesSetAllow(t *testing.T) {
if value != allowedList {
t.Fatal("Got the wrong value, set devices.allow failed.")
}
+
+ // When AllowAllDevices is nil, devices.allow file should not be modified.
+ helper.CgroupData.config.Resources.AllowAllDevices = nil
+ if err := devices.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
+ t.Fatal(err)
+ }
+ value, err = getCgroupParamString(helper.CgroupPath, "devices.allow")
+ if err != nil {
+ t.Fatalf("Failed to parse devices.allow - %s", err)
+ }
+ if value != allowedList {
+ t.Fatal("devices policy shouldn't have changed on AllowedAllDevices=nil.")
+ }
}
func TestDevicesSetDeny(t *testing.T) {
@@ -66,7 +79,8 @@ func TestDevicesSetDeny(t *testing.T) {
"devices.allow": "a",
})
- helper.CgroupData.config.Resources.AllowAllDevices = true
+ allowAllDevices := true
+ helper.CgroupData.config.Resources.AllowAllDevices = &allowAllDevices
helper.CgroupData.config.Resources.DeniedDevices = deniedDevices
devices := &DevicesGroup{}
if err := devices.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go
index 6b4a9eac..2a3ccf00 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go
@@ -5,15 +5,19 @@ package fs
import (
"bufio"
"fmt"
+ "io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
+ "syscall"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
)
+const cgroupKernelMemoryLimit = "memory.kmem.limit_in_bytes"
+
type MemoryGroup struct {
}
@@ -32,13 +36,12 @@ func (s *MemoryGroup) Apply(d *cgroupData) (err error) {
return err
}
}
- // We have to set kernel memory here, as we can't change it once
- // processes have been attached.
- if err := s.SetKernelMemory(path, d.config); err != nil {
- return err
+ if d.config.KernelMemory != 0 {
+ if err := EnableKernelMemoryAccounting(path); err != nil {
+ return err
+ }
}
}
-
defer func() {
if err != nil {
os.RemoveAll(path)
@@ -54,17 +57,44 @@ func (s *MemoryGroup) Apply(d *cgroupData) (err error) {
return nil
}
-func (s *MemoryGroup) SetKernelMemory(path string, cgroup *configs.Cgroup) error {
- // This has to be done separately because it has special constraints (it
- // can't be done after there are processes attached to the cgroup).
- if cgroup.Resources.KernelMemory > 0 {
- if err := writeFile(path, "memory.kmem.limit_in_bytes", strconv.FormatInt(cgroup.Resources.KernelMemory, 10)); err != nil {
+func EnableKernelMemoryAccounting(path string) error {
+ // Check if kernel memory is enabled
+ // We have to limit the kernel memory here as it won't be accounted at all
+ // until a limit is set on the cgroup and limit cannot be set once the
+ // cgroup has children, or if there are already tasks in the cgroup.
+ for _, i := range []int64{1, -1} {
+ if err := setKernelMemory(path, i); err != nil {
return err
}
}
return nil
}
+func setKernelMemory(path string, kernelMemoryLimit int64) error {
+ if path == "" {
+ return fmt.Errorf("no such directory for %s", cgroupKernelMemoryLimit)
+ }
+ if !cgroups.PathExists(filepath.Join(path, cgroupKernelMemoryLimit)) {
+ // kernel memory is not enabled on the system so we should do nothing
+ return nil
+ }
+ if err := ioutil.WriteFile(filepath.Join(path, cgroupKernelMemoryLimit), []byte(strconv.FormatInt(kernelMemoryLimit, 10)), 0700); err != nil {
+ // Check if the error number returned by the syscall is "EBUSY"
+ // The EBUSY signal is returned on attempts to write to the
+ // memory.kmem.limit_in_bytes file if the cgroup has children or
+ // once tasks have been attached to the cgroup
+ if pathErr, ok := err.(*os.PathError); ok {
+ if errNo, ok := pathErr.Err.(syscall.Errno); ok {
+ if errNo == syscall.EBUSY {
+ return fmt.Errorf("failed to set %s, because either tasks have already joined this cgroup or it has children", cgroupKernelMemoryLimit)
+ }
+ }
+ }
+ return fmt.Errorf("failed to write %v to %v: %v", kernelMemoryLimit, cgroupKernelMemoryLimit, err)
+ }
+ return nil
+}
+
func setMemoryAndSwap(path string, cgroup *configs.Cgroup) error {
// When memory and swap memory are both set, we need to handle the cases
// for updating container.
@@ -113,11 +143,18 @@ func (s *MemoryGroup) Set(path string, cgroup *configs.Cgroup) error {
return err
}
+ if cgroup.Resources.KernelMemory != 0 {
+ if err := setKernelMemory(path, cgroup.Resources.KernelMemory); err != nil {
+ return err
+ }
+ }
+
if cgroup.Resources.MemoryReservation != 0 {
if err := writeFile(path, "memory.soft_limit_in_bytes", strconv.FormatInt(cgroup.Resources.MemoryReservation, 10)); err != nil {
return err
}
}
+
if cgroup.Resources.KernelMemoryTCP != 0 {
if err := writeFile(path, "memory.kmem.tcp.limit_in_bytes", strconv.FormatInt(cgroup.Resources.KernelMemoryTCP, 10)); err != nil {
return err
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory_test.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory_test.go
index 16695e93..5e86e1b4 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory_test.go
@@ -230,7 +230,7 @@ func TestMemorySetKernelMemory(t *testing.T) {
helper.CgroupData.config.Resources.KernelMemory = kernelMemoryAfter
memory := &MemoryGroup{}
- if err := memory.SetKernelMemory(helper.CgroupPath, helper.CgroupData.config); err != nil {
+ if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
t.Fatal(err)
}
@@ -471,11 +471,11 @@ func TestMemorySetOomControl(t *testing.T) {
defer helper.cleanup()
const (
- oom_kill_disable = 1 // disable oom killer, default is 0
+ oomKillDisable = 1 // disable oom killer, default is 0
)
helper.writeFileContents(map[string]string{
- "memory.oom_control": strconv.Itoa(oom_kill_disable),
+ "memory.oom_control": strconv.Itoa(oomKillDisable),
})
memory := &MemoryGroup{}
@@ -488,7 +488,7 @@ func TestMemorySetOomControl(t *testing.T) {
t.Fatalf("Failed to parse memory.oom_control - %s", err)
}
- if value != oom_kill_disable {
+ if value != oomKillDisable {
t.Fatalf("Got the wrong value, set memory.oom_control failed.")
}
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls.go
index 8a4054ba..8e74b645 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls.go
@@ -3,6 +3,8 @@
package fs
import (
+ "strconv"
+
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
)
@@ -23,8 +25,8 @@ func (s *NetClsGroup) Apply(d *cgroupData) error {
}
func (s *NetClsGroup) Set(path string, cgroup *configs.Cgroup) error {
- if cgroup.Resources.NetClsClassid != "" {
- if err := writeFile(path, "net_cls.classid", cgroup.Resources.NetClsClassid); err != nil {
+ if cgroup.Resources.NetClsClassid != 0 {
+ if err := writeFile(path, "net_cls.classid", strconv.FormatUint(uint64(cgroup.Resources.NetClsClassid), 10)); err != nil {
return err
}
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls_test.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls_test.go
index 974bd9d8..c00e8a8d 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls_test.go
@@ -3,12 +3,13 @@
package fs
import (
+ "strconv"
"testing"
)
const (
- classidBefore = "0x100002"
- classidAfter = "0x100001"
+ classidBefore = 0x100002
+ classidAfter = 0x100001
)
func TestNetClsSetClassid(t *testing.T) {
@@ -16,7 +17,7 @@ func TestNetClsSetClassid(t *testing.T) {
defer helper.cleanup()
helper.writeFileContents(map[string]string{
- "net_cls.classid": classidBefore,
+ "net_cls.classid": strconv.FormatUint(classidBefore, 10),
})
helper.CgroupData.config.Resources.NetClsClassid = classidAfter
@@ -28,7 +29,7 @@ func TestNetClsSetClassid(t *testing.T) {
// As we are in mock environment, we can't get correct value of classid from
// net_cls.classid.
// So. we just judge if we successfully write classid into file
- value, err := getCgroupParamString(helper.CgroupPath, "net_cls.classid")
+ value, err := getCgroupParamUint(helper.CgroupPath, "net_cls.classid")
if err != nil {
t.Fatalf("Failed to parse net_cls.classid - %s", err)
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/utils.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/utils.go
index 852b1839..5ff0a161 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/utils.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/utils.go
@@ -12,7 +12,6 @@ import (
)
var (
- ErrNotSupportStat = errors.New("stats are not supported for subsystem")
ErrNotValidFormat = errors.New("line is not a valid key value format")
)
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go
index 797a923c..b483f1bf 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go
@@ -11,6 +11,7 @@ type ThrottlingData struct {
ThrottledTime uint64 `json:"throttled_time,omitempty"`
}
+// CpuUsage denotes the usage of a CPU.
// All CPU stats are aggregate since container inception.
type CpuUsage struct {
// Total CPU time consumed.
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go
index b6158095..fd428f90 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go
@@ -8,7 +8,6 @@ import (
"io/ioutil"
"os"
"path/filepath"
- "strconv"
"strings"
"sync"
"time"
@@ -67,13 +66,16 @@ var subsystems = subsystemSet{
const (
testScopeWait = 4
+ testSliceWait = 4
)
var (
connLock sync.Mutex
theConn *systemdDbus.Conn
hasStartTransientUnit bool
+ hasStartTransientSliceUnit bool
hasTransientDefaultDependencies bool
+ hasDelegate bool
)
func newProp(name string, units interface{}) systemdDbus.Property {
@@ -146,6 +148,48 @@ func UseSystemd() bool {
// Not critical because of the stop unit logic above.
theConn.StopUnit(scope, "replace", nil)
+
+ // Assume StartTransientUnit on a scope allows Delegate
+ hasDelegate = true
+ dl := newProp("Delegate", true)
+ if _, err := theConn.StartTransientUnit(scope, "replace", []systemdDbus.Property{dl}, nil); err != nil {
+ if dbusError, ok := err.(dbus.Error); ok {
+ if strings.Contains(dbusError.Name, "org.freedesktop.DBus.Error.PropertyReadOnly") {
+ hasDelegate = false
+ }
+ }
+ }
+
+ // Assume we have the ability to start a transient unit as a slice
+ // This was broken until systemd v229, but has been back-ported on RHEL environments >= 219
+ // For details, see: https://bugzilla.redhat.com/show_bug.cgi?id=1370299
+ hasStartTransientSliceUnit = true
+
+ // To ensure simple clean-up, we create a slice off the root with no hierarchy
+ slice := fmt.Sprintf("libcontainer_%d_systemd_test_default.slice", os.Getpid())
+ if _, err := theConn.StartTransientUnit(slice, "replace", nil, nil); err != nil {
+ if _, ok := err.(dbus.Error); ok {
+ hasStartTransientSliceUnit = false
+ }
+ }
+
+ for i := 0; i <= testSliceWait; i++ {
+ if _, err := theConn.StopUnit(slice, "replace", nil); err != nil {
+ if dbusError, ok := err.(dbus.Error); ok {
+ if strings.Contains(dbusError.Name, "org.freedesktop.systemd1.NoSuchUnit") {
+ hasStartTransientSliceUnit = false
+ break
+ }
+ }
+ } else {
+ break
+ }
+ time.Sleep(time.Millisecond)
+ }
+
+ // Not critical because of the stop unit logic above.
+ theConn.StopUnit(scope, "replace", nil)
+ theConn.StopUnit(slice, "replace", nil)
}
return hasStartTransientUnit
}
@@ -179,13 +223,29 @@ func (m *Manager) Apply(pid int) error {
slice = c.Parent
}
- properties = append(properties,
- systemdDbus.PropSlice(slice),
- systemdDbus.PropDescription("docker container "+c.Name),
- newProp("PIDs", []uint32{uint32(pid)}),
+ properties = append(properties, systemdDbus.PropDescription("libcontainer container "+c.Name))
+
+ // if we create a slice, the parent is defined via a Wants=
+ if strings.HasSuffix(unitName, ".slice") {
+ // This was broken until systemd v229, but has been back-ported on RHEL environments >= 219
+ if !hasStartTransientSliceUnit {
+ return fmt.Errorf("systemd version does not support ability to start a slice as transient unit")
+ }
+ properties = append(properties, systemdDbus.PropWants(slice))
+ } else {
+ // otherwise, we use Slice=
+ properties = append(properties, systemdDbus.PropSlice(slice))
+ }
+
+ // only add pid if its valid, -1 is used w/ general slice creation.
+ if pid != -1 {
+ properties = append(properties, newProp("PIDs", []uint32{uint32(pid)}))
+ }
+
+ if hasDelegate {
// This is only supported on systemd versions 218 and above.
- newProp("Delegate", true),
- )
+ properties = append(properties, newProp("Delegate", true))
+ }
// Always enable accounting, this gets us the same behaviour as the fs implementation,
// plus the kernel has some problems with joining the memory cgroup at a later time.
@@ -214,17 +274,15 @@ func (m *Manager) Apply(pid int) error {
newProp("BlockIOWeight", uint64(c.Resources.BlkioWeight)))
}
- // We need to set kernel memory before processes join cgroup because
- // kmem.limit_in_bytes can only be set when the cgroup is empty.
- // And swap memory limit needs to be set after memory limit, only
- // memory limit is handled by systemd, so it's kind of ugly here.
- if c.Resources.KernelMemory > 0 {
+ // We have to set kernel memory here, as we can't change it once
+ // processes have been attached to the cgroup.
+ if c.Resources.KernelMemory != 0 {
if err := setKernelMemory(c); err != nil {
return err
}
}
- if _, err := theConn.StartTransientUnit(unitName, "replace", properties, nil); err != nil {
+ if _, err := theConn.StartTransientUnit(unitName, "replace", properties, nil); err != nil && !isUnitExists(err) {
return err
}
@@ -273,7 +331,7 @@ func writeFile(dir, file, data string) error {
// Normally dir should not be empty, one case is that cgroup subsystem
// is not mounted, we will get empty dir, and we want it fail here.
if dir == "" {
- return fmt.Errorf("no such directory for %s.", file)
+ return fmt.Errorf("no such directory for %s", file)
}
return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700)
}
@@ -286,10 +344,9 @@ func join(c *configs.Cgroup, subsystem string, pid int) (string, error) {
if err := os.MkdirAll(path, 0755); err != nil {
return "", err
}
- if err := writeFile(path, "cgroup.procs", strconv.Itoa(pid)); err != nil {
+ if err := cgroups.WriteCgroupProc(path, pid); err != nil {
return "", err
}
-
return path, nil
}
@@ -331,10 +388,10 @@ func joinCgroups(c *configs.Cgroup, pid int) error {
return nil
}
-// systemd represents slice heirarchy using `-`, so we need to follow suit when
+// systemd represents slice hierarchy using `-`, so we need to follow suit when
// generating the path of slice. Essentially, test-a-b.slice becomes
// test.slice/test-a.slice/test-a-b.slice.
-func expandSlice(slice string) (string, error) {
+func ExpandSlice(slice string) (string, error) {
suffix := ".slice"
// Name has to end with ".slice", but can't be just ".slice".
if len(slice) < len(suffix) || !strings.HasSuffix(slice, suffix) {
@@ -348,6 +405,10 @@ func expandSlice(slice string) (string, error) {
var path, prefix string
sliceName := strings.TrimSuffix(slice, suffix)
+ // if input was -.slice, we should just return root now
+ if sliceName == "-" {
+ return "/", nil
+ }
for _, component := range strings.Split(sliceName, "-") {
// test--a.slice isn't permitted, nor is -test.slice.
if component == "" {
@@ -372,13 +433,15 @@ func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) {
if err != nil {
return "", err
}
+ // if pid 1 is systemd 226 or later, it will be in init.scope, not the root
+ initPath = strings.TrimSuffix(filepath.Clean(initPath), "init.scope")
slice := "system.slice"
if c.Parent != "" {
slice = c.Parent
}
- slice, err = expandSlice(slice)
+ slice, err = ExpandSlice(slice)
if err != nil {
return "", err
}
@@ -439,6 +502,11 @@ func (m *Manager) GetStats() (*cgroups.Stats, error) {
}
func (m *Manager) Set(container *configs.Config) error {
+ // If Paths are set, then we are just joining cgroups paths
+ // and there is no need to set any values.
+ if m.Cgroups.Paths != nil {
+ return nil
+ }
for _, sys := range subsystems {
// Get the subsystem path, but don't error out for not found cgroups.
path, err := getSubsystemPath(container.Cgroups, sys.Name())
@@ -460,7 +528,11 @@ func (m *Manager) Set(container *configs.Config) error {
}
func getUnitName(c *configs.Cgroup) string {
- return fmt.Sprintf("%s-%s.scope", c.ScopePrefix, c.Name)
+ // by default, we create a scope unless the user explicitly asks for a slice.
+ if !strings.HasSuffix(c.Name, ".slice") {
+ return fmt.Sprintf("%s-%s.scope", c.ScopePrefix, c.Name)
+ }
+ return c.Name
}
func setKernelMemory(c *configs.Cgroup) error {
@@ -472,8 +544,15 @@ func setKernelMemory(c *configs.Cgroup) error {
if err := os.MkdirAll(path, 0755); err != nil {
return err
}
-
- // This doesn't get called by manager.Set, so we need to do it here.
- s := &fs.MemoryGroup{}
- return s.SetKernelMemory(path, c)
+ return fs.EnableKernelMemoryAccounting(path)
+}
+
+// isUnitExists returns true if the error is that a systemd unit already exists.
+func isUnitExists(err error) bool {
+ if err != nil {
+ if dbusError, ok := err.(dbus.Error); ok {
+ return strings.Contains(dbusError.Name, "org.freedesktop.systemd1.UnitExists")
+ }
+ }
+ return false
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go
index 23527329..52fc87eb 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go
@@ -16,37 +16,24 @@ import (
"github.com/docker/go-units"
)
-const cgroupNamePrefix = "name="
+const (
+ cgroupNamePrefix = "name="
+ CgroupProcesses = "cgroup.procs"
+)
-// https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt
+// https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt
func FindCgroupMountpoint(subsystem string) (string, error) {
- // We are not using mount.GetMounts() because it's super-inefficient,
- // parsing it directly sped up x10 times because of not using Sscanf.
- // It was one of two major performance drawbacks in container start.
- f, err := os.Open("/proc/self/mountinfo")
- if err != nil {
- return "", err
- }
- defer f.Close()
-
- scanner := bufio.NewScanner(f)
- for scanner.Scan() {
- txt := scanner.Text()
- fields := strings.Split(txt, " ")
- for _, opt := range strings.Split(fields[len(fields)-1], ",") {
- if opt == subsystem {
- return fields[4], nil
- }
- }
- }
- if err := scanner.Err(); err != nil {
- return "", err
- }
-
- return "", NewNotFoundError(subsystem)
+ mnt, _, err := FindCgroupMountpointAndRoot(subsystem)
+ return mnt, err
}
func FindCgroupMountpointAndRoot(subsystem string) (string, string, error) {
+ // We are not using mount.GetMounts() because it's super-inefficient,
+ // parsing it directly sped up x10 times because of not using Sscanf.
+ // It was one of two major performance drawbacks in container start.
+ if !isSubsystemAvailable(subsystem) {
+ return "", "", NewNotFoundError(subsystem)
+ }
f, err := os.Open("/proc/self/mountinfo")
if err != nil {
return "", "", err
@@ -70,6 +57,15 @@ func FindCgroupMountpointAndRoot(subsystem string) (string, string, error) {
return "", "", NewNotFoundError(subsystem)
}
+func isSubsystemAvailable(subsystem string) bool {
+ cgroups, err := ParseCgroupFile("/proc/self/cgroup")
+ if err != nil {
+ return false
+ }
+ _, avail := cgroups[subsystem]
+ return avail
+}
+
func FindCgroupMountpointDir() (string, error) {
f, err := os.Open("/proc/self/mountinfo")
if err != nil {
@@ -121,16 +117,17 @@ func (m Mount) GetThisCgroupDir(cgroups map[string]string) (string, error) {
return getControllerPath(m.Subsystems[0], cgroups)
}
-func getCgroupMountsHelper(ss map[string]bool, mi io.Reader) ([]Mount, error) {
+func getCgroupMountsHelper(ss map[string]bool, mi io.Reader, all bool) ([]Mount, error) {
res := make([]Mount, 0, len(ss))
scanner := bufio.NewScanner(mi)
- for scanner.Scan() {
+ numFound := 0
+ for scanner.Scan() && numFound < len(ss) {
txt := scanner.Text()
sepIdx := strings.Index(txt, " - ")
if sepIdx == -1 {
return nil, fmt.Errorf("invalid mountinfo format")
}
- if txt[sepIdx+3:sepIdx+9] != "cgroup" {
+ if txt[sepIdx+3:sepIdx+10] == "cgroup2" || txt[sepIdx+3:sepIdx+9] != "cgroup" {
continue
}
fields := strings.Split(txt, " ")
@@ -139,12 +136,17 @@ func getCgroupMountsHelper(ss map[string]bool, mi io.Reader) ([]Mount, error) {
Root: fields[3],
}
for _, opt := range strings.Split(fields[len(fields)-1], ",") {
+ if !ss[opt] {
+ continue
+ }
if strings.HasPrefix(opt, cgroupNamePrefix) {
m.Subsystems = append(m.Subsystems, opt[len(cgroupNamePrefix):])
- }
- if ss[opt] {
+ } else {
m.Subsystems = append(m.Subsystems, opt)
}
+ if !all {
+ numFound++
+ }
}
res = append(res, m)
}
@@ -154,26 +156,28 @@ func getCgroupMountsHelper(ss map[string]bool, mi io.Reader) ([]Mount, error) {
return res, nil
}
-func GetCgroupMounts() ([]Mount, error) {
+// GetCgroupMounts returns the mounts for the cgroup subsystems.
+// all indicates whether to return just the first instance or all the mounts.
+func GetCgroupMounts(all bool) ([]Mount, error) {
f, err := os.Open("/proc/self/mountinfo")
if err != nil {
return nil, err
}
defer f.Close()
- all, err := GetAllSubsystems()
+ allSubsystems, err := ParseCgroupFile("/proc/self/cgroup")
if err != nil {
return nil, err
}
allMap := make(map[string]bool)
- for _, s := range all {
+ for s := range allSubsystems {
allMap[s] = true
}
- return getCgroupMountsHelper(allMap, f)
+ return getCgroupMountsHelper(allMap, f, all)
}
-// Returns all the cgroup subsystems supported by the kernel
+// GetAllSubsystems returns all the cgroup subsystems supported by the kernel
func GetAllSubsystems() ([]string, error) {
f, err := os.Open("/proc/cgroups")
if err != nil {
@@ -185,9 +189,6 @@ func GetAllSubsystems() ([]string, error) {
s := bufio.NewScanner(f)
for s.Scan() {
- if err := s.Err(); err != nil {
- return nil, err
- }
text := s.Text()
if text[0] != '#' {
parts := strings.Fields(text)
@@ -196,10 +197,13 @@ func GetAllSubsystems() ([]string, error) {
}
}
}
+ if err := s.Err(); err != nil {
+ return nil, err
+ }
return subsystems, nil
}
-// Returns the relative path to the cgroup docker is running in.
+// GetThisCgroupDir returns the relative path to the cgroup docker is running in.
func GetThisCgroupDir(subsystem string) (string, error) {
cgroups, err := ParseCgroupFile("/proc/self/cgroup")
if err != nil {
@@ -220,7 +224,7 @@ func GetInitCgroupDir(subsystem string) (string, error) {
}
func readProcsFile(dir string) ([]int, error) {
- f, err := os.Open(filepath.Join(dir, "cgroup.procs"))
+ f, err := os.Open(filepath.Join(dir, CgroupProcesses))
if err != nil {
return nil, err
}
@@ -243,6 +247,8 @@ func readProcsFile(dir string) ([]int, error) {
return out, nil
}
+// ParseCgroupFile parses the given cgroup file, typically from
+// /proc//cgroup, into a map of subgroups to cgroup names.
func ParseCgroupFile(path string) (map[string]string, error) {
f, err := os.Open(path)
if err != nil {
@@ -250,21 +256,35 @@ func ParseCgroupFile(path string) (map[string]string, error) {
}
defer f.Close()
- s := bufio.NewScanner(f)
+ return parseCgroupFromReader(f)
+}
+
+// helper function for ParseCgroupFile to make testing easier
+func parseCgroupFromReader(r io.Reader) (map[string]string, error) {
+ s := bufio.NewScanner(r)
cgroups := make(map[string]string)
for s.Scan() {
- if err := s.Err(); err != nil {
- return nil, err
- }
-
text := s.Text()
- parts := strings.Split(text, ":")
+ // from cgroups(7):
+ // /proc/[pid]/cgroup
+ // ...
+ // For each cgroup hierarchy ... there is one entry
+ // containing three colon-separated fields of the form:
+ // hierarchy-ID:subsystem-list:cgroup-path
+ parts := strings.SplitN(text, ":", 3)
+ if len(parts) < 3 {
+ return nil, fmt.Errorf("invalid cgroup entry: must contain at least two colons: %v", text)
+ }
for _, subs := range strings.Split(parts[1], ",") {
cgroups[subs] = parts[2]
}
}
+ if err := s.Err(); err != nil {
+ return nil, err
+ }
+
return cgroups, nil
}
@@ -291,8 +311,7 @@ func PathExists(path string) bool {
func EnterPid(cgroupPaths map[string]string, pid int) error {
for _, path := range cgroupPaths {
if PathExists(path) {
- if err := ioutil.WriteFile(filepath.Join(path, "cgroup.procs"),
- []byte(strconv.Itoa(pid)), 0700); err != nil {
+ if err := WriteCgroupProc(path, pid); err != nil {
return err
}
}
@@ -361,7 +380,7 @@ func GetAllPids(path string) ([]int, error) {
// collect pids from all sub-cgroups
err := filepath.Walk(path, func(p string, info os.FileInfo, iErr error) error {
dir, file := filepath.Split(p)
- if file != "cgroup.procs" {
+ if file != CgroupProcesses {
return nil
}
if iErr != nil {
@@ -376,3 +395,20 @@ func GetAllPids(path string) ([]int, error) {
})
return pids, err
}
+
+// WriteCgroupProc writes the specified pid into the cgroup's cgroup.procs file
+func WriteCgroupProc(dir string, pid int) error {
+ // Normally dir should not be empty, one case is that cgroup subsystem
+ // is not mounted, we will get empty dir, and we want it fail here.
+ if dir == "" {
+ return fmt.Errorf("no such directory for %s", CgroupProcesses)
+ }
+
+ // Dont attach any pid to the cgroup if -1 is specified as a pid
+ if pid != -1 {
+ if err := ioutil.WriteFile(filepath.Join(dir, CgroupProcesses), []byte(strconv.Itoa(pid)), 0700); err != nil {
+ return fmt.Errorf("failed to write %v to %v: %v", pid, CgroupProcesses, err)
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils_test.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils_test.go
index 47bbd5e2..d3aa8ef4 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils_test.go
@@ -4,6 +4,8 @@ package cgroups
import (
"bytes"
+ "fmt"
+ "reflect"
"strings"
"testing"
)
@@ -91,6 +93,34 @@ const systemdMountinfo = `115 83 0:32 / / rw,relatime - aufs none rw,si=c0bd3d3,
136 117 0:12 /1 /dev/console rw,nosuid,noexec,relatime - devpts none rw,gid=5,mode=620,ptmxmode=000
84 115 0:40 / /tmp rw,relatime - tmpfs none rw`
+const cgroup2Mountinfo = `18 64 0:18 / /sys rw,nosuid,nodev,noexec,relatime shared:6 - sysfs sysfs rw,seclabel
+19 64 0:4 / /proc rw,nosuid,nodev,noexec,relatime shared:5 - proc proc rw
+20 64 0:6 / /dev rw,nosuid shared:2 - devtmpfs devtmpfs rw,seclabel,size=8171204k,nr_inodes=2042801,mode=755
+21 18 0:19 / /sys/kernel/security rw,nosuid,nodev,noexec,relatime shared:7 - securityfs securityfs rw
+22 20 0:20 / /dev/shm rw,nosuid,nodev shared:3 - tmpfs tmpfs rw,seclabel
+23 20 0:21 / /dev/pts rw,nosuid,noexec,relatime shared:4 - devpts devpts rw,seclabel,gid=5,mode=620,ptmxmode=000
+24 64 0:22 / /run rw,nosuid,nodev shared:24 - tmpfs tmpfs rw,seclabel,mode=755
+25 18 0:23 / /sys/fs/cgroup ro,nosuid,nodev,noexec shared:8 - tmpfs tmpfs ro,seclabel,mode=755
+26 25 0:24 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime shared:9 - cgroup2 cgroup rw
+27 18 0:25 / /sys/fs/pstore rw,nosuid,nodev,noexec,relatime shared:20 - pstore pstore rw,seclabel
+28 18 0:26 / /sys/firmware/efi/efivars rw,nosuid,nodev,noexec,relatime shared:21 - efivarfs efivarfs rw
+29 25 0:27 / /sys/fs/cgroup/cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:10 - cgroup cgroup rw,cpu,cpuacct
+30 25 0:28 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime shared:11 - cgroup cgroup rw,memory
+31 25 0:29 / /sys/fs/cgroup/net_cls,net_prio rw,nosuid,nodev,noexec,relatime shared:12 - cgroup cgroup rw,net_cls,net_prio
+32 25 0:30 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:13 - cgroup cgroup rw,blkio
+33 25 0:31 / /sys/fs/cgroup/perf_event rw,nosuid,nodev,noexec,relatime shared:14 - cgroup cgroup rw,perf_event
+34 25 0:32 / /sys/fs/cgroup/hugetlb rw,nosuid,nodev,noexec,relatime shared:15 - cgroup cgroup rw,hugetlb
+35 25 0:33 / /sys/fs/cgroup/freezer rw,nosuid,nodev,noexec,relatime shared:16 - cgroup cgroup rw,freezer
+36 25 0:34 / /sys/fs/cgroup/cpuset rw,nosuid,nodev,noexec,relatime shared:17 - cgroup cgroup rw,cpuset
+37 25 0:35 / /sys/fs/cgroup/devices rw,nosuid,nodev,noexec,relatime shared:18 - cgroup cgroup rw,devices
+38 25 0:36 / /sys/fs/cgroup/pids rw,nosuid,nodev,noexec,relatime shared:19 - cgroup cgroup rw,pids
+61 18 0:37 / /sys/kernel/config rw,relatime shared:22 - configfs configfs rw
+64 0 253:0 / / rw,relatime shared:1 - ext4 /dev/mapper/fedora_dhcp--16--129-root rw,seclabel,data=ordered
+39 18 0:17 / /sys/fs/selinux rw,relatime shared:23 - selinuxfs selinuxfs rw
+40 20 0:16 / /dev/mqueue rw,relatime shared:25 - mqueue mqueue rw,seclabel
+41 20 0:39 / /dev/hugepages rw,relatime shared:26 - hugetlbfs hugetlbfs rw,seclabel
+`
+
func TestGetCgroupMounts(t *testing.T) {
type testData struct {
mountInfo string
@@ -132,7 +162,7 @@ func TestGetCgroupMounts(t *testing.T) {
}
for _, td := range testTable {
mi := bytes.NewBufferString(td.mountInfo)
- cgMounts, err := getCgroupMountsHelper(td.subsystems, mi)
+ cgMounts, err := getCgroupMountsHelper(td.subsystems, mi, false)
if err != nil {
t.Fatal(err)
}
@@ -185,8 +215,88 @@ func BenchmarkGetCgroupMounts(b *testing.B) {
b.StopTimer()
mi := bytes.NewBufferString(fedoraMountinfo)
b.StartTimer()
- if _, err := getCgroupMountsHelper(subsystems, mi); err != nil {
+ if _, err := getCgroupMountsHelper(subsystems, mi, false); err != nil {
b.Fatal(err)
}
}
}
+
+func TestParseCgroupString(t *testing.T) {
+ testCases := []struct {
+ input string
+ expectedError error
+ expectedOutput map[string]string
+ }{
+ {
+ // Taken from a CoreOS instance running systemd 225 with CPU/Mem
+ // accounting enabled in systemd
+ input: `9:blkio:/
+8:freezer:/
+7:perf_event:/
+6:devices:/system.slice/system-sshd.slice
+5:cpuset:/
+4:cpu,cpuacct:/system.slice/system-sshd.slice/sshd@126-10.240.0.15:22-xxx.yyy.zzz.aaa:33678.service
+3:net_cls,net_prio:/
+2:memory:/system.slice/system-sshd.slice/sshd@126-10.240.0.15:22-xxx.yyy.zzz.aaa:33678.service
+1:name=systemd:/system.slice/system-sshd.slice/sshd@126-10.240.0.15:22-xxx.yyy.zzz.aaa:33678.service`,
+ expectedOutput: map[string]string{
+ "name=systemd": "/system.slice/system-sshd.slice/sshd@126-10.240.0.15:22-xxx.yyy.zzz.aaa:33678.service",
+ "blkio": "/",
+ "freezer": "/",
+ "perf_event": "/",
+ "devices": "/system.slice/system-sshd.slice",
+ "cpuset": "/",
+ "cpu": "/system.slice/system-sshd.slice/sshd@126-10.240.0.15:22-xxx.yyy.zzz.aaa:33678.service",
+ "cpuacct": "/system.slice/system-sshd.slice/sshd@126-10.240.0.15:22-xxx.yyy.zzz.aaa:33678.service",
+ "net_cls": "/",
+ "net_prio": "/",
+ "memory": "/system.slice/system-sshd.slice/sshd@126-10.240.0.15:22-xxx.yyy.zzz.aaa:33678.service",
+ },
+ },
+ {
+ input: `malformed input`,
+ expectedError: fmt.Errorf(`invalid cgroup entry: must contain at least two colons: malformed input`),
+ },
+ }
+
+ for ndx, testCase := range testCases {
+ out, err := parseCgroupFromReader(strings.NewReader(testCase.input))
+ if err != nil {
+ if testCase.expectedError == nil || testCase.expectedError.Error() != err.Error() {
+ t.Errorf("%v: expected error %v, got error %v", ndx, testCase.expectedError, err)
+ }
+ } else {
+ if !reflect.DeepEqual(testCase.expectedOutput, out) {
+ t.Errorf("%v: expected output %v, got error %v", ndx, testCase.expectedOutput, out)
+ }
+ }
+ }
+
+}
+
+func TestIgnoreCgroup2Mount(t *testing.T) {
+ subsystems := map[string]bool{
+ "cpuset": true,
+ "cpu": true,
+ "cpuacct": true,
+ "memory": true,
+ "devices": true,
+ "freezer": true,
+ "net_cls": true,
+ "blkio": true,
+ "perf_event": true,
+ "pids": true,
+ "name=systemd": true,
+ }
+
+ mi := bytes.NewBufferString(cgroup2Mountinfo)
+ cgMounts, err := getCgroupMountsHelper(subsystems, mi, false)
+ if err != nil {
+ t.Fatal(err)
+ }
+ for _, m := range cgMounts {
+ if m.Mountpoint == "/sys/fs/cgroup/systemd" {
+ t.Errorf("parsed a cgroup2 mount at /sys/fs/cgroup/systemd instead of ignoring it")
+ }
+ }
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_unix.go
index f2eff91c..14d62898 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_unix.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_unix.go
@@ -22,7 +22,7 @@ type Cgroup struct {
// The path is assumed to be relative to the host system cgroup mountpoint.
Path string `json:"path"`
- // ScopePrefix decribes prefix for the scope name
+ // ScopePrefix describes prefix for the scope name
ScopePrefix string `json:"scope_prefix"`
// Paths represent the absolute cgroups paths to join.
@@ -36,7 +36,7 @@ type Cgroup struct {
type Resources struct {
// If this is true allow access to any kind of device within the container. If false, allow access only to devices explicitly listed in the allowed_devices list.
// Deprecated
- AllowAllDevices bool `json:"allow_all_devices,omitempty"`
+ AllowAllDevices *bool `json:"allow_all_devices,omitempty"`
// Deprecated
AllowedDevices []*Device `json:"allowed_devices,omitempty"`
// Deprecated
@@ -69,10 +69,10 @@ type Resources struct {
CpuPeriod int64 `json:"cpu_period"`
// How many time CPU will use in realtime scheduling (in usecs).
- CpuRtRuntime int64 `json:"cpu_quota"`
+ CpuRtRuntime int64 `json:"cpu_rt_quota"`
// CPU period to be used for realtime scheduling (in usecs).
- CpuRtPeriod int64 `json:"cpu_period"`
+ CpuRtPeriod int64 `json:"cpu_rt_period"`
// CPU to use
CpusetCpus string `json:"cpuset_cpus"`
@@ -95,7 +95,7 @@ type Resources struct {
// IO read rate limit per cgroup per device, bytes per second.
BlkioThrottleReadBpsDevice []*ThrottleDevice `json:"blkio_throttle_read_bps_device"`
- // IO write rate limit per cgroup per divice, bytes per second.
+ // IO write rate limit per cgroup per device, bytes per second.
BlkioThrottleWriteBpsDevice []*ThrottleDevice `json:"blkio_throttle_write_bps_device"`
// IO read rate limit per cgroup per device, IO per second.
@@ -120,5 +120,5 @@ type Resources struct {
NetPrioIfpriomap []*IfPrioMap `json:"net_prio_ifpriomap"`
// Set class identifier for container's network packets
- NetClsClassid string `json:"net_cls_classid"`
+ NetClsClassid uint32 `json:"net_cls_classid_u"`
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
index 1221ce27..dac08e44 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
@@ -8,6 +8,7 @@ import (
"time"
"github.com/Sirupsen/logrus"
+ "github.com/opencontainers/runtime-spec/specs-go"
)
type Rlimit struct {
@@ -33,7 +34,7 @@ type Seccomp struct {
Syscalls []*Syscall `json:"syscalls"`
}
-// An action to be taken upon rule match in Seccomp
+// Action is taken upon rule match in Seccomp
type Action int
const (
@@ -44,7 +45,7 @@ const (
Trace
)
-// A comparison operator to be used when matching syscall arguments in Seccomp
+// Operator is a comparison operator to be used when matching syscall arguments in Seccomp
type Operator int
const (
@@ -57,7 +58,7 @@ const (
MaskEqualTo
)
-// A rule to match a specific syscall argument in Seccomp
+// Arg is a rule to match a specific syscall argument in Seccomp
type Arg struct {
Index uint `json:"index"`
Value uint64 `json:"value"`
@@ -65,7 +66,7 @@ type Arg struct {
Op Operator `json:"op"`
}
-// An rule to match a syscall in Seccomp
+// Syscall is a rule to match a syscall in Seccomp
type Syscall struct {
Name string `json:"name"`
Action Action `json:"action"`
@@ -85,11 +86,6 @@ type Config struct {
// that the parent process dies.
ParentDeathSignal int `json:"parent_death_signal"`
- // PivotDir allows a custom directory inside the container's root filesystem to be used as pivot, when NoPivotRoot is not set.
- // When a custom PivotDir not set, a temporary dir inside the root filesystem will be used. The pivot dir needs to be writeable.
- // This is required when using read only root filesystems. In these cases, a read/writeable path can be (bind) mounted somewhere inside the root filesystem to act as pivot.
- PivotDir string `json:"pivot_dir"`
-
// Path to a directory containing the container's root filesystem.
Rootfs string `json:"rootfs"`
@@ -148,10 +144,6 @@ type Config struct {
// More information about kernel oom score calculation here: https://lwn.net/Articles/317814/
OomScoreAdj int `json:"oom_score_adj"`
- // AdditionalGroups specifies the gids that should be added to supplementary groups
- // in addition to those that the user belongs to.
- AdditionalGroups []string `json:"additional_groups"`
-
// UidMappings is an array of User ID mappings for User Namespaces
UidMappings []IDMap `json:"uid_mappings"`
@@ -187,6 +179,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 {
@@ -248,20 +244,14 @@ func (hooks Hooks) MarshalJSON() ([]byte, error) {
}
// HookState is the payload provided to a hook on execution.
-type HookState struct {
- Version string `json:"ociVersion"`
- ID string `json:"id"`
- Pid int `json:"pid"`
- Root string `json:"root"`
- BundlePath string `json:"bundlePath"`
-}
+type HookState specs.State
type Hook interface {
// Run executes the hook with the provided state.
Run(HookState) error
}
-// NewFunctionHooks will call the provided function when the hook is run.
+// NewFunctionHook will call the provided function when the hook is run.
func NewFunctionHook(f func(HookState) error) FuncHook {
return FuncHook{
run: f,
@@ -284,7 +274,7 @@ type Command struct {
Timeout *time.Duration `json:"timeout"`
}
-// NewCommandHooks will execute the provided command when the hook is run.
+// NewCommandHook will execute the provided command when the hook is run.
func NewCommandHook(cmd Command) CommandHook {
return CommandHook{
Command: cmd,
@@ -300,29 +290,38 @@ func (c Command) Run(s HookState) error {
if err != nil {
return err
}
+ var stdout, stderr bytes.Buffer
cmd := exec.Cmd{
- Path: c.Path,
- Args: c.Args,
- Env: c.Env,
- Stdin: bytes.NewReader(b),
+ Path: c.Path,
+ Args: c.Args,
+ Env: c.Env,
+ Stdin: bytes.NewReader(b),
+ Stdout: &stdout,
+ Stderr: &stderr,
+ }
+ if err := cmd.Start(); err != nil {
+ return err
}
errC := make(chan error, 1)
go func() {
- out, err := cmd.CombinedOutput()
+ err := cmd.Wait()
if err != nil {
- err = fmt.Errorf("%s: %s", err, out)
+ err = fmt.Errorf("error running hook: %v, stdout: %s, stderr: %s", err, stdout.String(), stderr.String())
}
errC <- err
}()
+ var timerCh <-chan time.Time
if c.Timeout != nil {
- select {
- case err := <-errC:
- return err
- case <-time.After(*c.Timeout):
- cmd.Process.Kill()
- cmd.Wait()
- return fmt.Errorf("hook ran past specified timeout of %.1fs", c.Timeout.Seconds())
- }
+ timer := time.NewTimer(*c.Timeout)
+ defer timer.Stop()
+ timerCh = timer.C
+ }
+ select {
+ case err := <-errC:
+ return err
+ case <-timerCh:
+ cmd.Process.Kill()
+ cmd.Wait()
+ return fmt.Errorf("hook ran past specified timeout of %.1fs", c.Timeout.Seconds())
}
- return <-errC
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/config_test.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/config_test.go
index 006a772a..381a906b 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/config_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/config_test.go
@@ -120,10 +120,10 @@ func TestMarshalHooksWithUnexpectedType(t *testing.T) {
func TestFuncHookRun(t *testing.T) {
state := configs.HookState{
- Version: "1",
- ID: "1",
- Pid: 1,
- Root: "root",
+ Version: "1",
+ ID: "1",
+ Pid: 1,
+ BundlePath: "/bundle",
}
fHook := configs.NewFunctionHook(func(s configs.HookState) error {
@@ -138,10 +138,10 @@ func TestFuncHookRun(t *testing.T) {
func TestCommandHookRun(t *testing.T) {
state := configs.HookState{
- Version: "1",
- ID: "1",
- Pid: 1,
- Root: "root",
+ Version: "1",
+ ID: "1",
+ Pid: 1,
+ BundlePath: "/bundle",
}
timeout := time.Second
@@ -161,10 +161,10 @@ func TestCommandHookRun(t *testing.T) {
func TestCommandHookRunTimeout(t *testing.T) {
state := configs.HookState{
- Version: "1",
- ID: "1",
- Pid: 1,
- Root: "root",
+ Version: "1",
+ ID: "1",
+ Pid: 1,
+ BundlePath: "/bundle",
}
timeout := (10 * time.Millisecond)
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/config_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/config_unix.go
index c447f3ef..a60554a7 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/config_unix.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/config_unix.go
@@ -4,7 +4,7 @@ package configs
import "fmt"
-// Gets the root uid for the process on host which could be non-zero
+// HostUID gets the root uid for the process on host which could be non-zero
// when user namespaces are enabled.
func (c Config) HostUID() (int, error) {
if c.Namespaces.Contains(NEWUSER) {
@@ -21,7 +21,7 @@ func (c Config) HostUID() (int, error) {
return 0, nil
}
-// Gets the root gid for the process on host which could be non-zero
+// HostGID gets the root gid for the process on host which could be non-zero
// when user namespaces are enabled.
func (c Config) HostGID() (int, error) {
if c.Namespaces.Contains(NEWUSER) {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/config_unix_test.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/config_unix_test.go
index 27d07d4e..dc01cd01 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/config_unix_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/config_unix_test.go
@@ -10,30 +10,6 @@ import (
"testing"
)
-// Checks whether the expected capability is specified in the capabilities.
-func contains(expected string, values []string) bool {
- for _, v := range values {
- if v == expected {
- return true
- }
- }
- return false
-}
-
-func containsDevice(expected *Device, values []*Device) bool {
- for _, d := range values {
- if d.Path == expected.Path &&
- d.Permissions == expected.Permissions &&
- d.FileMode == expected.FileMode &&
- d.Major == expected.Major &&
- d.Minor == expected.Minor &&
- d.Type == expected.Type {
- return true
- }
- }
- return false
-}
-
func loadConfig(name string) (*Config, error) {
f, err := os.Open(filepath.Join("../sample_configs", name))
if err != nil {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/device_defaults.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/device_defaults.go
index e4529926..4d348d21 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/device_defaults.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/device_defaults.go
@@ -3,7 +3,7 @@
package configs
var (
- // These are devices that are to be both allowed and created.
+ // DefaultSimpleDevices are devices that are to be both allowed and created.
DefaultSimpleDevices = []*Device{
// /dev/null and zero
{
@@ -107,19 +107,5 @@ var (
Permissions: "rwm",
},
}, DefaultSimpleDevices...)
- DefaultAutoCreatedDevices = append([]*Device{
- {
- // /dev/fuse is created but not allowed.
- // This is to allow java to work. Because java
- // Insists on there being a /dev/fuse
- // https://github.com/docker/docker/issues/514
- // https://github.com/docker/docker/issues/2393
- //
- Path: "/dev/fuse",
- Type: 'c',
- Major: 10,
- Minor: 229,
- Permissions: "rwm",
- },
- }, DefaultSimpleDevices...)
+ DefaultAutoCreatedDevices = append([]*Device{}, DefaultSimpleDevices...)
)
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/mount.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/mount.go
index cc770c91..670757dd 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/mount.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/mount.go
@@ -1,5 +1,11 @@
package configs
+const (
+ // EXT_COPYUP is a directive to copy up the contents of a directory when
+ // a tmpfs is mounted over it.
+ EXT_COPYUP = 1 << iota
+)
+
type Mount struct {
// Source path for the mount.
Source string `json:"source"`
@@ -22,6 +28,9 @@ type Mount struct {
// Relabel source if set, "z" indicates shared, "Z" indicates unshared.
Relabel string `json:"relabel"`
+ // Extensions are additional flags that are specific to runc.
+ Extensions int `json:"extensions"`
+
// Optional Command to be run before Source is mounted.
PremountCmds []Command `json:"premount_cmds"`
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_syscall_unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_syscall_unsupported.go
index 0547223a..5d9a5c81 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_syscall_unsupported.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_syscall_unsupported.go
@@ -4,12 +4,10 @@ package configs
func (n *Namespace) Syscall() int {
panic("No namespace syscall support")
- return 0
}
// CloneFlags parses the container's Namespaces options to set the correct
// flags on clone, unshare. This function returns flags only for new namespaces.
func (n *Namespaces) CloneFlags() uintptr {
panic("No namespace syscall support")
- return uintptr(0)
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_unix.go
index b9c820d0..8beba9d3 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_unix.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_unix.go
@@ -22,8 +22,8 @@ var (
supportedNamespaces = make(map[NamespaceType]bool)
)
-// nsToFile converts the namespace type to its filename
-func nsToFile(ns NamespaceType) string {
+// NsName converts the namespace type to its filename
+func NsName(ns NamespaceType) string {
switch ns {
case NEWNET:
return "net"
@@ -50,7 +50,7 @@ func IsNamespaceSupported(ns NamespaceType) bool {
if ok {
return supported
}
- nsFile := nsToFile(ns)
+ nsFile := NsName(ns)
// if the namespace type is unknown, just return false
if nsFile == "" {
return false
@@ -84,7 +84,7 @@ func (n *Namespace) GetPath(pid int) string {
if n.Path != "" {
return n.Path
}
- return fmt.Sprintf("/proc/%d/ns/%s", pid, nsToFile(n.Type))
+ return fmt.Sprintf("/proc/%d/ns/%s", pid, NsName(n.Type))
}
func (n *Namespaces) Remove(t NamespaceType) bool {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go
index bd6964c5..f076f506 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go
@@ -7,6 +7,7 @@ import (
"strings"
"github.com/opencontainers/runc/libcontainer/configs"
+ "github.com/opencontainers/runc/libcontainer/selinux"
)
type Validator interface {
@@ -45,6 +46,12 @@ func (v *ConfigValidator) Validate(config *configs.Config) error {
// rootfs validates if the rootfs is an absolute path and is not a symlink
// to the container's root filesystem.
func (v *ConfigValidator) rootfs(config *configs.Config) error {
+ if _, err := os.Stat(config.Rootfs); err != nil {
+ if os.IsNotExist(err) {
+ return fmt.Errorf("rootfs (%s) does not exist", config.Rootfs)
+ }
+ return err
+ }
cleaned, err := filepath.Abs(config.Rootfs)
if err != nil {
return err
@@ -80,6 +87,10 @@ func (v *ConfigValidator) security(config *configs.Config) error {
!config.Namespaces.Contains(configs.NEWNS) {
return fmt.Errorf("unable to restrict sys entries without a private MNT namespace")
}
+ if config.ProcessLabel != "" && !selinux.SelinuxEnabled() {
+ return fmt.Errorf("selinux label is specified in config, but selinux is disabled or not supported")
+ }
+
return nil
}
@@ -121,6 +132,11 @@ func (v *ConfigValidator) sysctl(config *configs.Config) error {
}
if strings.HasPrefix(s, "net.") {
if config.Namespaces.Contains(configs.NEWNET) {
+ if path := config.Namespaces.PathOf(configs.NEWNET); path != "" {
+ if err := checkHostNs(s, path); err != nil {
+ return err
+ }
+ }
continue
} else {
return fmt.Errorf("sysctl %q is not allowed in the hosts network namespace", s)
@@ -131,3 +147,44 @@ func (v *ConfigValidator) sysctl(config *configs.Config) error {
return nil
}
+
+func isSymbolicLink(path string) (bool, error) {
+ fi, err := os.Lstat(path)
+ if err != nil {
+ return false, err
+ }
+
+ return fi.Mode()&os.ModeSymlink == os.ModeSymlink, nil
+}
+
+// checkHostNs checks whether network sysctl is used in host namespace.
+func checkHostNs(sysctlConfig string, path string) error {
+ var currentProcessNetns = "/proc/self/ns/net"
+ // readlink on the current processes network namespace
+ destOfCurrentProcess, err := os.Readlink(currentProcessNetns)
+ if err != nil {
+ return fmt.Errorf("read soft link %q error", currentProcessNetns)
+ }
+
+ // First check if the provided path is a symbolic link
+ symLink, err := isSymbolicLink(path)
+ if err != nil {
+ return fmt.Errorf("could not check that %q is a symlink: %v", path, err)
+ }
+
+ if symLink == false {
+ // The provided namespace is not a symbolic link,
+ // it is not the host namespace.
+ return nil
+ }
+
+ // readlink on the path provided in the struct
+ destOfContainer, err := os.Readlink(path)
+ if err != nil {
+ return fmt.Errorf("read soft link %q error", path)
+ }
+ if destOfContainer == destOfCurrentProcess {
+ return fmt.Errorf("sysctl %q is not allowed in the hosts network namespace", sysctlConfig)
+ }
+ return nil
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator_test.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator_test.go
index 8775f33a..f6826fb3 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator_test.go
@@ -100,7 +100,7 @@ func TestValidateHostnameWithoutUTSNamespace(t *testing.T) {
func TestValidateSecurityWithMaskPaths(t *testing.T) {
config := &configs.Config{
Rootfs: "/var",
- MaskPaths: []string{"/proc/kcores"},
+ MaskPaths: []string{"/proc/kcore"},
Namespaces: configs.Namespaces(
[]configs.Namespace{
{Type: configs.NEWNS},
@@ -136,7 +136,7 @@ func TestValidateSecurityWithROPaths(t *testing.T) {
func TestValidateSecurityWithoutNEWNS(t *testing.T) {
config := &configs.Config{
Rootfs: "/var",
- MaskPaths: []string{"/proc/kcores"},
+ MaskPaths: []string{"/proc/kcore"},
ReadonlyPaths: []string{"/proc/sys"},
}
@@ -148,6 +148,9 @@ func TestValidateSecurityWithoutNEWNS(t *testing.T) {
}
func TestValidateUsernamespace(t *testing.T) {
+ if _, err := os.Stat("/proc/self/ns/user"); os.IsNotExist(err) {
+ t.Skip("userns is unsupported")
+ }
config := &configs.Config{
Rootfs: "/var",
Namespaces: configs.Namespaces(
@@ -198,3 +201,67 @@ func TestValidateSysctl(t *testing.T) {
}
}
}
+
+func TestValidateValidSysctl(t *testing.T) {
+ sysctl := map[string]string{
+ "fs.mqueue.ctl": "ctl",
+ "net.ctl": "ctl",
+ "kernel.msgmax": "ctl",
+ }
+
+ for k, v := range sysctl {
+ config := &configs.Config{
+ Rootfs: "/var",
+ Sysctl: map[string]string{k: v},
+ Namespaces: []configs.Namespace{
+ {
+ Type: configs.NEWNET,
+ },
+ {
+ Type: configs.NEWIPC,
+ },
+ },
+ }
+
+ validator := validate.New()
+ err := validator.Validate(config)
+ if err != nil {
+ t.Errorf("Expected error to not occur with {%s=%s} but got: %q", k, v, err)
+ }
+ }
+}
+
+func TestValidateSysctlWithSameNs(t *testing.T) {
+ config := &configs.Config{
+ Rootfs: "/var",
+ Sysctl: map[string]string{"net.ctl": "ctl"},
+ Namespaces: configs.Namespaces(
+ []configs.Namespace{
+ {
+ Type: configs.NEWNET,
+ Path: "/proc/self/ns/net",
+ },
+ },
+ ),
+ }
+
+ validator := validate.New()
+ err := validator.Validate(config)
+ if err == nil {
+ t.Error("Expected error to occur but it was nil")
+ }
+}
+
+func TestValidateSysctlWithoutNETNamespace(t *testing.T) {
+ config := &configs.Config{
+ Rootfs: "/var",
+ Sysctl: map[string]string{"net.ctl": "ctl"},
+ Namespaces: []configs.Namespace{},
+ }
+
+ validator := validate.New()
+ err := validator.Validate(config)
+ if err == nil {
+ t.Error("Expected error to occur but it was nil")
+ }
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/console.go b/vendor/github.com/opencontainers/runc/libcontainer/console.go
index 042a2a2e..d19043f4 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/console.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/console.go
@@ -1,15 +1,73 @@
package libcontainer
-import "io"
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "os"
+)
// Console represents a pseudo TTY.
type Console interface {
- io.ReadWriter
- io.Closer
+ io.ReadWriteCloser
// Path returns the filesystem path to the slave side of the pty.
Path() string
// Fd returns the fd for the master of the pty.
- Fd() uintptr
+ File() *os.File
+}
+
+const (
+ TerminalInfoVersion uint32 = 201610041
+ TerminalInfoType uint8 = 'T'
+)
+
+// TerminalInfo is the structure which is passed as the non-ancillary data
+// in the sendmsg(2) call when runc is run with --console-socket. It
+// contains some information about the container which the console master fd
+// relates to (to allow for consumers to use a single unix socket to handle
+// multiple containers). This structure will probably move to runtime-spec
+// at some point. But for now it lies in libcontainer.
+type TerminalInfo struct {
+ // Version of the API.
+ Version uint32 `json:"version"`
+
+ // Type of message (future proofing).
+ Type uint8 `json:"type"`
+
+ // Container contains the ID of the container.
+ ContainerID string `json:"container_id"`
+}
+
+func (ti *TerminalInfo) String() string {
+ encoded, err := json.Marshal(*ti)
+ if err != nil {
+ panic(err)
+ }
+ return string(encoded)
+}
+
+func NewTerminalInfo(containerId string) *TerminalInfo {
+ return &TerminalInfo{
+ Version: TerminalInfoVersion,
+ Type: TerminalInfoType,
+ ContainerID: containerId,
+ }
+}
+
+func GetTerminalInfo(encoded string) (*TerminalInfo, error) {
+ ti := new(TerminalInfo)
+ if err := json.Unmarshal([]byte(encoded), ti); err != nil {
+ return nil, err
+ }
+
+ if ti.Type != TerminalInfoType {
+ return nil, fmt.Errorf("terminal info: incorrect type in payload (%q): %q", TerminalInfoType, ti.Type)
+ }
+ if ti.Version != TerminalInfoVersion {
+ return nil, fmt.Errorf("terminal info: incorrect version in payload (%q): %q", TerminalInfoVersion, ti.Version)
+ }
+
+ return ti, nil
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/console_freebsd.go b/vendor/github.com/opencontainers/runc/libcontainer/console_freebsd.go
index 3c89eda0..b7166a31 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/console_freebsd.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/console_freebsd.go
@@ -6,8 +6,8 @@ import (
"errors"
)
-// NewConsole returns an initalized console that can be used within a container by copying bytes
+// newConsole returns an initialized console that can be used within a container by copying bytes
// from the master side to the slave that is attached as the tty for the container's init process.
-func NewConsole(uid, gid int) (Console, error) {
+func newConsole() (Console, error) {
return nil, errors.New("libcontainer console is not supported on FreeBSD")
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/console_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/console_linux.go
index 7af771b6..6e38b462 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/console_linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/console_linux.go
@@ -3,20 +3,20 @@ package libcontainer
import (
"fmt"
"os"
- "path/filepath"
"syscall"
"unsafe"
-
- "github.com/opencontainers/runc/libcontainer/label"
)
-// NewConsole returns an initalized console that can be used within a container by copying bytes
+// newConsole returns an initialized console that can be used within a container by copying bytes
// from the master side to the slave that is attached as the tty for the container's init process.
-func NewConsole(uid, gid int) (Console, error) {
+func newConsole() (Console, error) {
master, err := os.OpenFile("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0)
if err != nil {
return nil, err
}
+ if err := saneTerminal(master); err != nil {
+ return nil, err
+ }
console, err := ptsname(master)
if err != nil {
return nil, err
@@ -24,34 +24,20 @@ func NewConsole(uid, gid int) (Console, error) {
if err := unlockpt(master); err != nil {
return nil, err
}
- if err := os.Chmod(console, 0600); err != nil {
- return nil, err
- }
- if err := os.Chown(console, uid, gid); err != nil {
- return nil, err
- }
return &linuxConsole{
slavePath: console,
master: master,
}, nil
}
-// newConsoleFromPath is an internal function returning an initialized console for use inside
-// a container's MNT namespace.
-func newConsoleFromPath(slavePath string) *linuxConsole {
- return &linuxConsole{
- slavePath: slavePath,
- }
-}
-
-// linuxConsole is a linux psuedo TTY for use within a container.
+// linuxConsole is a linux pseudo TTY for use within a container.
type linuxConsole struct {
master *os.File
slavePath string
}
-func (c *linuxConsole) Fd() uintptr {
- return c.master.Fd()
+func (c *linuxConsole) File() *os.File {
+ return c.master
}
func (c *linuxConsole) Path() string {
@@ -75,21 +61,17 @@ func (c *linuxConsole) Close() error {
// mount initializes the console inside the rootfs mounting with the specified mount label
// and applying the correct ownership of the console.
-func (c *linuxConsole) mount(rootfs, mountLabel string) error {
+func (c *linuxConsole) mount() error {
oldMask := syscall.Umask(0000)
defer syscall.Umask(oldMask)
- if err := label.SetFileLabel(c.slavePath, mountLabel); err != nil {
- return err
- }
- dest := filepath.Join(rootfs, "/dev/console")
- f, err := os.Create(dest)
+ f, err := os.Create("/dev/console")
if err != nil && !os.IsExist(err) {
return err
}
if f != nil {
f.Close()
}
- return syscall.Mount(c.slavePath, dest, "bind", syscall.MS_BIND, "")
+ return syscall.Mount(c.slavePath, "/dev/console", "bind", syscall.MS_BIND, "")
}
// dupStdio opens the slavePath for the console and dups the fds to the current
@@ -143,3 +125,26 @@ func ptsname(f *os.File) (string, error) {
}
return fmt.Sprintf("/dev/pts/%d", n), nil
}
+
+// saneTerminal sets the necessary tty_ioctl(4)s to ensure that a pty pair
+// created by us acts normally. In particular, a not-very-well-known default of
+// Linux unix98 ptys is that they have +onlcr by default. While this isn't a
+// problem for terminal emulators, because we relay data from the terminal we
+// also relay that funky line discipline.
+func saneTerminal(terminal *os.File) error {
+ // Go doesn't have a wrapper for any of the termios ioctls.
+ var termios syscall.Termios
+
+ if err := ioctl(terminal.Fd(), syscall.TCGETS, uintptr(unsafe.Pointer(&termios))); err != nil {
+ return fmt.Errorf("ioctl(tty, tcgets): %s", err.Error())
+ }
+
+ // Set -onlcr so we don't have to deal with \r.
+ termios.Oflag &^= syscall.ONLCR
+
+ if err := ioctl(terminal.Fd(), syscall.TCSETS, uintptr(unsafe.Pointer(&termios))); err != nil {
+ return fmt.Errorf("ioctl(tty, tcsets): %s", err.Error())
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/console_solaris.go b/vendor/github.com/opencontainers/runc/libcontainer/console_solaris.go
new file mode 100644
index 00000000..e5ca5459
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/console_solaris.go
@@ -0,0 +1,11 @@
+package libcontainer
+
+import (
+ "errors"
+)
+
+// newConsole returns an initialized console that can be used within a container by copying bytes
+// from the master side to the slave that is attached as the tty for the container's init process.
+func newConsole() (Console, error) {
+ return nil, errors.New("libcontainer console is not supported on Solaris")
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/console_windows.go b/vendor/github.com/opencontainers/runc/libcontainer/console_windows.go
index a68c02f6..c61e866a 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/console_windows.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/console_windows.go
@@ -1,11 +1,11 @@
package libcontainer
-// NewConsole returns an initalized console that can be used within a container
-func NewConsole(uid, gid int) (Console, error) {
+// newConsole returns an initialized console that can be used within a container
+func newConsole() (Console, error) {
return &windowsConsole{}, nil
}
-// windowsConsole is a Windows psuedo TTY for use within a container.
+// windowsConsole is a Windows pseudo TTY for use within a container.
type windowsConsole struct {
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/container.go b/vendor/github.com/opencontainers/runc/libcontainer/container.go
index 32daa976..3ddb5ec6 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/container.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/container.go
@@ -1,4 +1,4 @@
-// Libcontainer provides a native Go implementation for creating containers
+// Package libcontainer provides a native Go implementation for creating containers
// with namespaces, cgroups, capabilities, and filesystem access controls.
// It allows you to manage the lifecycle of the container performing additional operations
// after the container is created.
@@ -11,24 +11,20 @@ import (
"github.com/opencontainers/runc/libcontainer/configs"
)
-// The status of a container.
+// Status is the status of a container.
type Status int
const (
- // The container exists but has not been run yet
+ // Created is the status that denotes the container exists but has not been run yet.
Created Status = iota
-
- // The container exists and is running.
+ // Running is the status that denotes the container exists and is running.
Running
-
- // The container exists, it is in the process of being paused.
+ // Pausing is the status that denotes the container exists, it is in the process of being paused.
Pausing
-
- // The container exists, but all its processes are paused.
+ // Paused is the status that denotes the container exists, but all its processes are paused.
Paused
-
- // The container does not exist.
- Destroyed
+ // Stopped is the status that denotes the container does not have a created or running process.
+ Stopped
)
func (s Status) String() string {
@@ -41,8 +37,8 @@ func (s Status) String() string {
return "pausing"
case Paused:
return "paused"
- case Destroyed:
- return "destroyed"
+ case Stopped:
+ return "stopped"
default:
return "unknown"
}
@@ -67,7 +63,7 @@ type BaseState struct {
Config configs.Config `json:"config"`
}
-// A libcontainer container object.
+// BaseContainer is a libcontainer container object.
//
// Each container is thread-safe within the same process. Since a container can
// be destroyed by a separate process, any function may return that the container
@@ -79,14 +75,14 @@ type BaseContainer interface {
// Returns the current status of the container.
//
// errors:
- // ContainerDestroyed - Container no longer exists,
+ // ContainerNotExists - Container no longer exists,
// Systemerror - System error.
Status() (Status, error)
// State returns the current container's state information.
//
// errors:
- // Systemerror - System error.
+ // SystemError - System error.
State() (*State, error)
// Returns the current config of the container.
@@ -95,7 +91,7 @@ type BaseContainer interface {
// Returns the PIDs inside this container. The PIDs are in the namespace of the calling process.
//
// errors:
- // ContainerDestroyed - Container no longer exists,
+ // ContainerNotExists - Container no longer exists,
// Systemerror - System error.
//
// Some of the returned PIDs may no longer refer to processes in the Container, unless
@@ -105,7 +101,7 @@ type BaseContainer interface {
// Returns statistics for the container.
//
// errors:
- // ContainerDestroyed - Container no longer exists,
+ // ContainerNotExists - Container no longer exists,
// Systemerror - System error.
Stats() (*Stats, error)
@@ -114,31 +110,57 @@ type BaseContainer interface {
// We can use this to change resources when containers are running.
//
// errors:
- // Systemerror - System error.
+ // SystemError - System error.
Set(config configs.Config) error
// Start a process inside the container. Returns error if process fails to
// start. You can track process lifecycle with passed Process structure.
//
// errors:
- // ContainerDestroyed - Container no longer exists,
+ // ContainerNotExists - Container no longer exists,
// ConfigInvalid - config is invalid,
// ContainerPaused - Container is paused,
- // Systemerror - System error.
+ // SystemError - System error.
Start(process *Process) (err error)
- // Destroys the container after killing all running processes.
+ // Run immediately starts the process inside the container. Returns error if process
+ // fails to start. It does not block waiting for the exec fifo after start returns but
+ // opens the fifo after start returns.
+ //
+ // errors:
+ // ContainerNotExists - Container no longer exists,
+ // ConfigInvalid - config is invalid,
+ // ContainerPaused - Container is paused,
+ // SystemError - System error.
+ Run(process *Process) (err error)
+
+ // Destroys the container, if its in a valid state, after killing any
+ // remaining running processes.
//
// Any event registrations are removed before the container is destroyed.
// No error is returned if the container is already destroyed.
//
+ // Running containers must first be stopped using Signal(..).
+ // Paused containers must first be resumed using Resume(..).
+ //
// errors:
- // Systemerror - System error.
+ // ContainerNotStopped - Container is still running,
+ // ContainerPaused - Container is paused,
+ // SystemError - System error.
Destroy() error
// Signal sends the provided signal code to the container's initial process.
//
+ // If all is specified the signal is sent to all processes in the container
+ // including the initial process.
+ //
// errors:
- // Systemerror - System error.
- Signal(s os.Signal) error
+ // SystemError - System error.
+ Signal(s os.Signal, all bool) error
+
+ // Exec signals the container to exec the users process at the end of the init.
+ //
+ // errors:
+ // SystemError - System error.
+ Exec() error
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/container_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/container_linux.go
index 2ae50c46..9f0043fb 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/container_linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/container_linux.go
@@ -22,6 +22,7 @@ import (
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/criurpc"
+ "github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/runc/libcontainer/utils"
"github.com/syndtr/gocapability/capability"
"github.com/vishvananda/netlink/nl"
@@ -30,18 +31,18 @@ import (
const stdioFdCount = 3
type linuxContainer struct {
- id string
- root string
- config *configs.Config
- cgroupManager cgroups.Manager
- initPath string
- initArgs []string
- initProcess parentProcess
- criuPath string
- m sync.Mutex
- criuVersion int
- state containerState
- created time.Time
+ id string
+ root string
+ config *configs.Config
+ cgroupManager cgroups.Manager
+ initArgs []string
+ initProcess parentProcess
+ initProcessStartTime string
+ criuPath string
+ m sync.Mutex
+ criuVersion int
+ state containerState
+ created time.Time
}
// State represents a running container's state
@@ -62,7 +63,7 @@ type State struct {
ExternalDescriptors []string `json:"external_descriptors,omitempty"`
}
-// A libcontainer container object.
+// Container is a libcontainer container object.
//
// Each container is thread-safe within the same process. Since a container can
// be destroyed by a separate process, any function may return that the container
@@ -84,13 +85,14 @@ type Container interface {
// Systemerror - System error.
Restore(process *Process, criuOpts *CriuOpts) error
- // If the Container state is RUNNING or PAUSING, sets the Container state to PAUSING and pauses
+ // If the Container state is RUNNING or CREATED, sets the Container state to PAUSING and pauses
// the execution of any user processes. Asynchronously, when the container finished being paused the
// state is changed to PAUSED.
// If the Container state is PAUSED, do nothing.
//
// errors:
- // ContainerDestroyed - Container no longer exists,
+ // ContainerNotExists - Container no longer exists,
+ // ContainerNotRunning - Container not running or created,
// Systemerror - System error.
Pause() error
@@ -99,7 +101,8 @@ type Container interface {
// If the Container state is RUNNING, do nothing.
//
// errors:
- // ContainerDestroyed - Container no longer exists,
+ // ContainerNotExists - Container no longer exists,
+ // ContainerNotPaused - Container is not paused,
// Systemerror - System error.
Resume() error
@@ -141,7 +144,7 @@ func (c *linuxContainer) State() (*State, error) {
func (c *linuxContainer) Processes() ([]int, error) {
pids, err := c.cgroupManager.GetAllPids()
if err != nil {
- return nil, newSystemError(err)
+ return nil, newSystemErrorWithCause(err, "getting all container pids from cgroups")
}
return pids, nil
}
@@ -152,14 +155,14 @@ func (c *linuxContainer) Stats() (*Stats, error) {
stats = &Stats{}
)
if stats.CgroupStats, err = c.cgroupManager.GetStats(); err != nil {
- return stats, newSystemError(err)
+ return stats, newSystemErrorWithCause(err, "getting container stats from cgroups")
}
for _, iface := range c.config.Networks {
switch iface.Type {
case "veth":
istats, err := getNetworkInterfaceStats(iface.HostInterfaceName)
if err != nil {
- return stats, newSystemError(err)
+ return stats, newSystemErrorWithCausef(err, "getting network stats for interface %q", iface.HostInterfaceName)
}
stats.Interfaces = append(stats.Interfaces, istats)
}
@@ -170,6 +173,13 @@ func (c *linuxContainer) Stats() (*Stats, error) {
func (c *linuxContainer) Set(config configs.Config) error {
c.m.Lock()
defer c.m.Unlock()
+ status, err := c.currentStatus()
+ if err != nil {
+ return err
+ }
+ if status == Stopped {
+ return newGenericError(fmt.Errorf("container not running"), ContainerNotRunning)
+ }
c.config = &config
return c.cgroupManager.Set(c.config)
}
@@ -181,42 +191,89 @@ func (c *linuxContainer) Start(process *Process) error {
if err != nil {
return err
}
- doInit := status == Destroyed
- parent, err := c.newParentProcess(process, doInit)
+ return c.start(process, status == Stopped)
+}
+
+func (c *linuxContainer) Run(process *Process) error {
+ c.m.Lock()
+ defer c.m.Unlock()
+ status, err := c.currentStatus()
if err != nil {
- return newSystemError(err)
+ return err
+ }
+ if err := c.start(process, status == Stopped); err != nil {
+ return err
+ }
+ if status == Stopped {
+ return c.exec()
+ }
+ return nil
+}
+
+func (c *linuxContainer) Exec() error {
+ c.m.Lock()
+ defer c.m.Unlock()
+ return c.exec()
+}
+
+func (c *linuxContainer) exec() error {
+ path := filepath.Join(c.root, execFifoFilename)
+ f, err := os.OpenFile(path, os.O_RDONLY, 0)
+ if err != nil {
+ return newSystemErrorWithCause(err, "open exec fifo for reading")
+ }
+ defer f.Close()
+ data, err := ioutil.ReadAll(f)
+ if err != nil {
+ return err
+ }
+ if len(data) > 0 {
+ os.Remove(path)
+ return nil
+ }
+ return fmt.Errorf("cannot start an already running container")
+}
+
+func (c *linuxContainer) start(process *Process, isInit bool) error {
+ parent, err := c.newParentProcess(process, isInit)
+ if err != nil {
+ return newSystemErrorWithCause(err, "creating new parent process")
}
if err := parent.start(); err != nil {
// terminate the process to ensure that it properly is reaped.
if err := parent.terminate(); err != nil {
logrus.Warn(err)
}
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "starting container process")
}
// generate a timestamp indicating when the container was started
c.created = time.Now().UTC()
-
c.state = &runningState{
c: c,
}
- if doInit {
- if err := c.updateState(parent); err != nil {
+ if isInit {
+ c.state = &createdState{
+ c: c,
+ }
+ state, err := c.updateState(parent)
+ if err != nil {
return err
}
+ c.initProcessStartTime = state.InitProcessStartTime
+
if c.config.Hooks != nil {
s := configs.HookState{
Version: c.config.Version,
ID: c.id,
Pid: parent.pid(),
- Root: c.config.Rootfs,
BundlePath: utils.SearchLabels(c.config.Labels, "bundle"),
}
- for _, hook := range c.config.Hooks.Poststart {
+ for i, hook := range c.config.Hooks.Poststart {
if err := hook.Run(s); err != nil {
if err := parent.terminate(); err != nil {
logrus.Warn(err)
}
- return newSystemError(err)
+ return newSystemErrorWithCausef(err, "running poststart hook %d", i)
}
}
}
@@ -224,9 +281,12 @@ func (c *linuxContainer) Start(process *Process) error {
return nil
}
-func (c *linuxContainer) Signal(s os.Signal) error {
+func (c *linuxContainer) Signal(s os.Signal, all bool) error {
+ if all {
+ return signalAllProcesses(c.cgroupManager, s)
+ }
if err := c.initProcess.signal(s); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "signaling init process")
}
return nil
}
@@ -234,23 +294,32 @@ func (c *linuxContainer) Signal(s os.Signal) error {
func (c *linuxContainer) newParentProcess(p *Process, doInit bool) (parentProcess, error) {
parentPipe, childPipe, err := newPipe()
if err != nil {
- return nil, newSystemError(err)
+ return nil, newSystemErrorWithCause(err, "creating new init pipe")
}
cmd, err := c.commandTemplate(p, childPipe)
if err != nil {
- return nil, newSystemError(err)
+ return nil, newSystemErrorWithCause(err, "creating new command template")
}
if !doInit {
return c.newSetnsProcess(p, cmd, parentPipe, childPipe)
}
- return c.newInitProcess(p, cmd, parentPipe, childPipe)
+
+ // We only set up rootDir if we're not doing a `runc exec`. The reason for
+ // this is to avoid cases where a racing, unprivileged process inside the
+ // container can get access to the statedir file descriptor (which would
+ // allow for container rootfs escape).
+ rootDir, err := os.Open(c.root)
+ if err != nil {
+ return nil, err
+ }
+ cmd.ExtraFiles = append(cmd.ExtraFiles, rootDir)
+ cmd.Env = append(cmd.Env,
+ fmt.Sprintf("_LIBCONTAINER_STATEDIR=%d", stdioFdCount+len(cmd.ExtraFiles)-1))
+ return c.newInitProcess(p, cmd, parentPipe, childPipe, rootDir)
}
func (c *linuxContainer) commandTemplate(p *Process, childPipe *os.File) (*exec.Cmd, error) {
- cmd := &exec.Cmd{
- Path: c.initPath,
- Args: c.initArgs,
- }
+ cmd := exec.Command(c.initArgs[0], c.initArgs[1:]...)
cmd.Stdin = p.Stdin
cmd.Stdout = p.Stdout
cmd.Stderr = p.Stderr
@@ -259,7 +328,8 @@ func (c *linuxContainer) commandTemplate(p *Process, childPipe *os.File) (*exec.
cmd.SysProcAttr = &syscall.SysProcAttr{}
}
cmd.ExtraFiles = append(p.ExtraFiles, childPipe)
- cmd.Env = append(cmd.Env, fmt.Sprintf("_LIBCONTAINER_INITPIPE=%d", stdioFdCount+len(cmd.ExtraFiles)-1))
+ cmd.Env = append(cmd.Env,
+ fmt.Sprintf("_LIBCONTAINER_INITPIPE=%d", stdioFdCount+len(cmd.ExtraFiles)-1))
// NOTE: when running a container with no PID namespace and the parent process spawning the container is
// PID1 the pdeathsig is being delivered to the container's init process by the kernel for some reason
// even with the parent still running.
@@ -269,7 +339,7 @@ func (c *linuxContainer) commandTemplate(p *Process, childPipe *os.File) (*exec.
return cmd, nil
}
-func (c *linuxContainer) newInitProcess(p *Process, cmd *exec.Cmd, parentPipe, childPipe *os.File) (*initProcess, error) {
+func (c *linuxContainer) newInitProcess(p *Process, cmd *exec.Cmd, parentPipe, childPipe, rootDir *os.File) (*initProcess, error) {
cmd.Env = append(cmd.Env, "_LIBCONTAINER_INITTYPE="+string(initStandard))
nsMaps := make(map[configs.NamespaceType]string)
for _, ns := range c.config.Namespaces {
@@ -278,10 +348,11 @@ func (c *linuxContainer) newInitProcess(p *Process, cmd *exec.Cmd, parentPipe, c
}
}
_, sharePidns := nsMaps[configs.NEWPID]
- data, err := c.bootstrapData(c.config.Namespaces.CloneFlags(), nsMaps, "")
+ data, err := c.bootstrapData(c.config.Namespaces.CloneFlags(), nsMaps)
if err != nil {
return nil, err
}
+ p.consoleChan = make(chan *os.File, 1)
return &initProcess{
cmd: cmd,
childPipe: childPipe,
@@ -292,6 +363,7 @@ func (c *linuxContainer) newInitProcess(p *Process, cmd *exec.Cmd, parentPipe, c
process: p,
bootstrapData: data,
sharePidns: sharePidns,
+ rootDir: rootDir,
}, nil
}
@@ -299,15 +371,16 @@ func (c *linuxContainer) newSetnsProcess(p *Process, cmd *exec.Cmd, parentPipe,
cmd.Env = append(cmd.Env, "_LIBCONTAINER_INITTYPE="+string(initSetns))
state, err := c.currentState()
if err != nil {
- return nil, newSystemError(err)
+ return nil, newSystemErrorWithCause(err, "getting container's current state")
}
- // for setns process, we dont have to set cloneflags as the process namespaces
+ // for setns process, we don't have to set cloneflags as the process namespaces
// will only be set via setns syscall
- data, err := c.bootstrapData(0, state.NamespacePaths, p.consolePath)
+ data, err := c.bootstrapData(0, state.NamespacePaths)
if err != nil {
return nil, err
}
// TODO: set on container for process management
+ p.consoleChan = make(chan *os.File, 1)
return &setnsProcess{
cmd: cmd,
cgroupPaths: c.cgroupManager.GetPaths(),
@@ -325,8 +398,8 @@ func (c *linuxContainer) newInitConfig(process *Process) *initConfig {
Args: process.Args,
Env: process.Env,
User: process.User,
+ AdditionalGroups: process.AdditionalGroups,
Cwd: process.Cwd,
- Console: process.consolePath,
Capabilities: process.Capabilities,
PassedFilesCount: len(process.ExtraFiles),
ContainerId: c.ID(),
@@ -334,6 +407,7 @@ func (c *linuxContainer) newInitConfig(process *Process) *initConfig {
AppArmorProfile: c.config.AppArmorProfile,
ProcessLabel: c.config.ProcessLabel,
Rlimits: c.config.Rlimits,
+ ExecFifoPath: filepath.Join(c.root, execFifoFilename),
}
if process.NoNewPrivileges != nil {
cfg.NoNewPrivileges = *process.NoNewPrivileges
@@ -347,6 +421,17 @@ func (c *linuxContainer) newInitConfig(process *Process) *initConfig {
if len(process.Rlimits) > 0 {
cfg.Rlimits = process.Rlimits
}
+ /*
+ * TODO: This should not be automatically computed. We should implement
+ * this as a field in libcontainer.Process, and then we only dup the
+ * new console over the file descriptors which were not explicitly
+ * set with process.Std{in,out,err}. The reason I've left this as-is
+ * is because the GetConsole() interface is new, there's no need to
+ * polish this interface right now.
+ */
+ if process.Stdin == nil && process.Stdout == nil && process.Stderr == nil {
+ cfg.CreateConsole = true
+ }
return cfg
}
@@ -371,15 +456,16 @@ func (c *linuxContainer) Pause() error {
if err != nil {
return err
}
- if status != Running {
- return newGenericError(fmt.Errorf("container not running"), ContainerNotRunning)
+ switch status {
+ case Running, Created:
+ if err := c.cgroupManager.Freeze(configs.Frozen); err != nil {
+ return err
+ }
+ return c.state.transition(&pausedState{
+ c: c,
+ })
}
- if err := c.cgroupManager.Freeze(configs.Frozen); err != nil {
- return err
- }
- return c.state.transition(&pausedState{
- c: c,
- })
+ return newGenericError(fmt.Errorf("container not running or created: %s", status), ContainerNotRunning)
}
func (c *linuxContainer) Resume() error {
@@ -408,13 +494,13 @@ func (c *linuxContainer) NotifyMemoryPressure(level PressureLevel) (<-chan struc
return notifyMemoryPressure(c.cgroupManager.GetPaths(), level)
}
-// check Criu version greater than or equal to min_version
-func (c *linuxContainer) checkCriuVersion(min_version string) error {
+// checkCriuVersion checks Criu version greater than or equal to minVersion
+func (c *linuxContainer) checkCriuVersion(minVersion string) error {
var x, y, z, versionReq int
- _, err := fmt.Sscanf(min_version, "%d.%d.%d\n", &x, &y, &z) // 1.5.2
+ _, err := fmt.Sscanf(minVersion, "%d.%d.%d\n", &x, &y, &z) // 1.5.2
if err != nil {
- _, err = fmt.Sscanf(min_version, "Version: %d.%d\n", &x, &y) // 1.6
+ _, err = fmt.Sscanf(minVersion, "Version: %d.%d\n", &x, &y) // 1.6
}
versionReq = x*10000 + y*100 + z
@@ -459,7 +545,7 @@ func (c *linuxContainer) checkCriuVersion(min_version string) error {
c.criuVersion = x*10000 + y*100 + z
if c.criuVersion < versionReq {
- return fmt.Errorf("CRIU version must be %s or higher", min_version)
+ return fmt.Errorf("CRIU version must be %s or higher", minVersion)
}
return nil
@@ -480,6 +566,29 @@ func (c *linuxContainer) addCriuDumpMount(req *criurpc.CriuReq, m *configs.Mount
req.Opts.ExtMnt = append(req.Opts.ExtMnt, extMnt)
}
+func (c *linuxContainer) addMaskPaths(req *criurpc.CriuReq) error {
+ for _, path := range c.config.MaskPaths {
+ fi, err := os.Stat(fmt.Sprintf("/proc/%d/root/%s", c.initProcess.pid(), path))
+ if err != nil {
+ if os.IsNotExist(err) {
+ continue
+ }
+ return err
+ }
+ if fi.IsDir() {
+ continue
+ }
+
+ extMnt := &criurpc.ExtMountMap{
+ Key: proto.String(path),
+ Val: proto.String("/dev/null"),
+ }
+ req.Opts.ExtMnt = append(req.Opts.ExtMnt, extMnt)
+ }
+
+ return nil
+}
+
func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
c.m.Lock()
defer c.m.Unlock()
@@ -575,6 +684,15 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
}
}
+ if err := c.addMaskPaths(req); err != nil {
+ return err
+ }
+
+ for _, node := range c.config.Devices {
+ m := &configs.Mount{Destination: node.Path, Source: node.Path}
+ c.addCriuDumpMount(req, m)
+ }
+
// Write the FD info to a file in the image directory
fdsJSON, err := json.Marshal(c.initProcess.externalDescriptors())
@@ -607,6 +725,27 @@ func (c *linuxContainer) addCriuRestoreMount(req *criurpc.CriuReq, m *configs.Mo
req.Opts.ExtMnt = append(req.Opts.ExtMnt, extMnt)
}
+func (c *linuxContainer) restoreNetwork(req *criurpc.CriuReq, criuOpts *CriuOpts) {
+ for _, iface := range c.config.Networks {
+ switch iface.Type {
+ case "veth":
+ veth := new(criurpc.CriuVethPair)
+ veth.IfOut = proto.String(iface.HostInterfaceName)
+ veth.IfIn = proto.String(iface.Name)
+ req.Opts.Veths = append(req.Opts.Veths, veth)
+ break
+ case "loopback":
+ break
+ }
+ }
+ for _, i := range criuOpts.VethPairs {
+ veth := new(criurpc.CriuVethPair)
+ veth.IfOut = proto.String(i.HostInterfaceName)
+ veth.IfIn = proto.String(i.ContainerInterfaceName)
+ req.Opts.Veths = append(req.Opts.Veths, veth)
+ }
+}
+
func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
c.m.Lock()
defer c.m.Unlock()
@@ -690,23 +829,19 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
break
}
}
- for _, iface := range c.config.Networks {
- switch iface.Type {
- case "veth":
- veth := new(criurpc.CriuVethPair)
- veth.IfOut = proto.String(iface.HostInterfaceName)
- veth.IfIn = proto.String(iface.Name)
- req.Opts.Veths = append(req.Opts.Veths, veth)
- break
- case "loopback":
- break
- }
+
+ if len(c.config.MaskPaths) > 0 {
+ m := &configs.Mount{Destination: "/dev/null", Source: "/dev/null"}
+ c.addCriuRestoreMount(req, m)
}
- for _, i := range criuOpts.VethPairs {
- veth := new(criurpc.CriuVethPair)
- veth.IfOut = proto.String(i.HostInterfaceName)
- veth.IfIn = proto.String(i.ContainerInterfaceName)
- req.Opts.Veths = append(req.Opts.Veths, veth)
+
+ for _, node := range c.config.Devices {
+ m := &configs.Mount{Destination: node.Path, Source: node.Path}
+ c.addCriuRestoreMount(req, m)
+ }
+
+ if criuOpts.EmptyNs&syscall.CLONE_NEWNET == 0 {
+ c.restoreNetwork(req, criuOpts)
}
// append optional manage cgroups mode
@@ -950,14 +1085,14 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
case notify.GetScript() == "setup-namespaces":
if c.config.Hooks != nil {
s := configs.HookState{
- Version: c.config.Version,
- ID: c.id,
- Pid: int(notify.GetPid()),
- Root: c.config.Rootfs,
+ Version: c.config.Version,
+ ID: c.id,
+ Pid: int(notify.GetPid()),
+ BundlePath: utils.SearchLabels(c.config.Labels, "bundle"),
}
- for _, hook := range c.config.Hooks.Prestart {
+ for i, hook := range c.config.Hooks.Prestart {
if err := hook.Run(s); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCausef(err, "running prestart hook %d", i)
}
}
}
@@ -974,7 +1109,9 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
}); err != nil {
return err
}
- if err := c.updateState(r); err != nil {
+ // create a timestamp indicating when the restored checkpoint was started
+ c.created = time.Now().UTC()
+ if _, err := c.updateState(r); err != nil {
return err
}
if err := os.Remove(filepath.Join(c.root, "checkpoint")); err != nil {
@@ -986,13 +1123,17 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
return nil
}
-func (c *linuxContainer) updateState(process parentProcess) error {
+func (c *linuxContainer) updateState(process parentProcess) (*State, error) {
c.initProcess = process
state, err := c.currentState()
if err != nil {
- return err
+ return nil, err
}
- return c.saveState(state)
+ err = c.saveState(state)
+ if err != nil {
+ return nil, err
+ }
+ return state, nil
}
func (c *linuxContainer) saveState(s *State) error {
@@ -1027,37 +1168,75 @@ func (c *linuxContainer) refreshState() error {
if paused {
return c.state.transition(&pausedState{c: c})
}
- running, err := c.isRunning()
+ t, err := c.runType()
if err != nil {
return err
}
- if running {
+ switch t {
+ case Created:
+ return c.state.transition(&createdState{c: c})
+ case Running:
return c.state.transition(&runningState{c: c})
}
return c.state.transition(&stoppedState{c: c})
}
-func (c *linuxContainer) isRunning() (bool, error) {
- if c.initProcess == nil {
+// doesInitProcessExist checks if the init process is still the same process
+// as the initial one, it could happen that the original process has exited
+// and a new process has been created with the same pid, in this case, the
+// container would already be stopped.
+func (c *linuxContainer) doesInitProcessExist(initPid int) (bool, error) {
+ startTime, err := system.GetProcessStartTime(initPid)
+ if err != nil {
+ return false, newSystemErrorWithCausef(err, "getting init process %d start time", initPid)
+ }
+ if c.initProcessStartTime != startTime {
return false, nil
}
- // return Running if the init process is alive
- if err := syscall.Kill(c.initProcess.pid(), 0); err != nil {
- if err == syscall.ESRCH {
- return false, nil
- }
- return false, newSystemError(err)
- }
return true, nil
}
+func (c *linuxContainer) runType() (Status, error) {
+ if c.initProcess == nil {
+ return Stopped, nil
+ }
+ pid := c.initProcess.pid()
+ // return Running if the init process is alive
+ if err := syscall.Kill(pid, 0); err != nil {
+ if err == syscall.ESRCH {
+ // It means the process does not exist anymore, could happen when the
+ // process exited just when we call the function, we should not return
+ // error in this case.
+ return Stopped, nil
+ }
+ return Stopped, newSystemErrorWithCausef(err, "sending signal 0 to pid %d", pid)
+ }
+ // check if the process is still the original init process.
+ exist, err := c.doesInitProcessExist(pid)
+ if !exist || err != nil {
+ return Stopped, err
+ }
+ // check if the process that is running is the init process or the user's process.
+ // this is the difference between the container Running and Created.
+ environ, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/environ", pid))
+ if err != nil {
+ return Stopped, newSystemErrorWithCausef(err, "reading /proc/%d/environ", pid)
+ }
+ check := []byte("_LIBCONTAINER")
+ if bytes.Contains(environ, check) {
+ return Created, nil
+ }
+ return Running, nil
+}
+
func (c *linuxContainer) isPaused() (bool, error) {
data, err := ioutil.ReadFile(filepath.Join(c.cgroupManager.GetPaths()["freezer"], "freezer.state"))
if err != nil {
+ // If freezer cgroup is not mounted, the container would just be not paused.
if os.IsNotExist(err) {
return false, nil
}
- return false, newSystemError(err)
+ return false, newSystemErrorWithCause(err, "checking if container is paused")
}
return bytes.Equal(bytes.TrimSpace(data), []byte("FROZEN")), nil
}
@@ -1106,16 +1285,22 @@ func (c *linuxContainer) currentState() (*State, error) {
// can setns in order.
func (c *linuxContainer) orderNamespacePaths(namespaces map[configs.NamespaceType]string) ([]string, error) {
paths := []string{}
- nsTypes := []configs.NamespaceType{
+ order := []configs.NamespaceType{
+ // The user namespace *must* be done first.
+ configs.NEWUSER,
configs.NEWIPC,
configs.NEWUTS,
configs.NEWNET,
configs.NEWPID,
configs.NEWNS,
}
- // join userns if the init process explicitly requires NEWUSER
- if c.config.Namespaces.Contains(configs.NEWUSER) {
- nsTypes = append(nsTypes, configs.NEWUSER)
+
+ // Remove namespaces that we don't need to join.
+ var nsTypes []configs.NamespaceType
+ for _, ns := range order {
+ if c.config.Namespaces.Contains(ns) {
+ nsTypes = append(nsTypes, ns)
+ }
}
for _, nsType := range nsTypes {
if p, ok := namespaces[nsType]; ok && p != "" {
@@ -1125,14 +1310,14 @@ func (c *linuxContainer) orderNamespacePaths(namespaces map[configs.NamespaceTyp
}
// only set to join this namespace if it exists
if _, err := os.Lstat(p); err != nil {
- return nil, newSystemError(err)
+ return nil, newSystemErrorWithCausef(err, "running lstat on namespace path %q", p)
}
// do not allow namespace path with comma as we use it to separate
// the namespace paths
if strings.ContainsRune(p, ',') {
return nil, newSystemError(fmt.Errorf("invalid path %s", p))
}
- paths = append(paths, p)
+ paths = append(paths, fmt.Sprintf("%s:%s", configs.NsName(nsType), p))
}
}
return paths, nil
@@ -1155,7 +1340,7 @@ func encodeIDMapping(idMap []configs.IDMap) ([]byte, error) {
// such as one that uses nsenter package to bootstrap the container's
// init process correctly, i.e. with correct namespaces, uid/gid
// mapping etc.
-func (c *linuxContainer) bootstrapData(cloneFlags uintptr, nsMaps map[configs.NamespaceType]string, consolePath string) (io.Reader, error) {
+func (c *linuxContainer) bootstrapData(cloneFlags uintptr, nsMaps map[configs.NamespaceType]string) (io.Reader, error) {
// create the netlink message
r := nl.NewNetlinkRequest(int(InitMsg), 0)
@@ -1165,14 +1350,6 @@ func (c *linuxContainer) bootstrapData(cloneFlags uintptr, nsMaps map[configs.Na
Value: uint32(cloneFlags),
})
- // write console path
- if consolePath != "" {
- r.AddData(&Bytemsg{
- Type: ConsolePathAttr,
- Value: []byte(consolePath),
- })
- }
-
// write custom namespace paths
if len(nsMaps) > 0 {
nsPaths, err := c.orderNamespacePaths(nsMaps)
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/container_linux_test.go b/vendor/github.com/opencontainers/runc/libcontainer/container_linux_test.go
index 3af30bce..b7ce552e 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/container_linux_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/container_linux_test.go
@@ -79,11 +79,11 @@ func (m *mockProcess) signal(_ os.Signal) error {
return nil
}
-func (p *mockProcess) externalDescriptors() []string {
+func (m *mockProcess) externalDescriptors() []string {
return []string{}
}
-func (p *mockProcess) setExternalDescriptors(newFds []string) {
+func (m *mockProcess) setExternalDescriptors(newFds []string) {
}
func TestGetContainerPids(t *testing.T) {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/container_solaris.go b/vendor/github.com/opencontainers/runc/libcontainer/container_solaris.go
new file mode 100644
index 00000000..bb84ff74
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/container_solaris.go
@@ -0,0 +1,20 @@
+package libcontainer
+
+// State represents a running container's state
+type State struct {
+ BaseState
+
+ // Platform specific fields below here
+}
+
+// A libcontainer container object.
+//
+// Each container is thread-safe within the same process. Since a container can
+// be destroyed by a separate process, any function may return that the container
+// was not found.
+type Container interface {
+ BaseContainer
+
+ // Methods below here are platform specific
+
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/criu_opts_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/criu_opts_unix.go
index 13323858..b163fbbb 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/criu_opts_unix.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/criu_opts_unix.go
@@ -3,13 +3,13 @@
package libcontainer
// cgroup restoring strategy provided by criu
-type cg_mode uint32
+type cgMode uint32
const (
- CRIU_CG_MODE_SOFT cg_mode = 3 + iota // restore cgroup properties if only dir created by criu
- CRIU_CG_MODE_FULL // always restore all cgroups and their properties
- CRIU_CG_MODE_STRICT // restore all, requiring them to not present in the system
- CRIU_CG_MODE_DEFAULT // the same as CRIU_CG_MODE_SOFT
+ CRIU_CG_MODE_SOFT cgMode = 3 + iota // restore cgroup properties if only dir created by criu
+ CRIU_CG_MODE_FULL // always restore all cgroups and their properties
+ CRIU_CG_MODE_STRICT // restore all, requiring them to not present in the system
+ CRIU_CG_MODE_DEFAULT // the same as CRIU_CG_MODE_SOFT
)
type CriuPageServerInfo struct {
@@ -32,6 +32,6 @@ type CriuOpts struct {
FileLocks bool // handle file locks, for safety
PageServer CriuPageServerInfo // allow to dump to criu page server
VethPairs []VethPairName // pass the veth to criu when restore
- ManageCgroupsMode cg_mode // dump or restore cgroup mode
+ ManageCgroupsMode cgMode // dump or restore cgroup mode
EmptyNs uint32 // don't c/r properties for namespace from this mask
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_unix.go
index c02b73e3..61c0c0c6 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_unix.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_unix.go
@@ -23,7 +23,7 @@ var (
ioutilReadDir = ioutil.ReadDir
)
-// Given the path to a device and it's cgroup_permissions(which cannot be easily queried) look up the information about a linux device and return that information as a Device struct.
+// Given the path to a device and its cgroup_permissions(which cannot be easily queried) look up the information about a linux device and return that information as a Device struct.
func DeviceFromPath(path, permissions string) (*configs.Device, error) {
fileInfo, err := osLstat(path)
if err != nil {
@@ -94,6 +94,9 @@ func getDevices(path string) ([]*configs.Device, error) {
if err == ErrNotADevice {
continue
}
+ if os.IsNotExist(err) {
+ continue
+ }
return nil, err
}
out = append(out, device)
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/error.go b/vendor/github.com/opencontainers/runc/libcontainer/error.go
index b50aaae8..21a3789b 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/error.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/error.go
@@ -2,7 +2,7 @@ package libcontainer
import "io"
-// API error code type.
+// ErrorCode is the API error code type.
type ErrorCode int
// API error codes.
@@ -56,13 +56,13 @@ func (c ErrorCode) String() string {
}
}
-// API Error type.
+// Error is the API error type.
type Error interface {
error
- // Returns a verbose string including the error message
- // and a representation of the stack trace suitable for
- // printing.
+ // Returns an error if it failed to write the detail of the Error to w.
+ // The detail of the Error may include the error message and a
+ // representation of the stack trace.
Detail(w io.Writer) error
// Returns the error code for this error.
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/error_test.go b/vendor/github.com/opencontainers/runc/libcontainer/error_test.go
index 4bf4c9f5..36841ad8 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/error_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/error_test.go
@@ -4,12 +4,17 @@ import "testing"
func TestErrorCode(t *testing.T) {
codes := map[ErrorCode]string{
- IdInUse: "Id already in use",
- InvalidIdFormat: "Invalid format",
- ContainerPaused: "Container paused",
- ConfigInvalid: "Invalid configuration",
- SystemError: "System error",
- ContainerNotExists: "Container does not exist",
+ IdInUse: "Id already in use",
+ InvalidIdFormat: "Invalid format",
+ ContainerPaused: "Container paused",
+ ConfigInvalid: "Invalid configuration",
+ SystemError: "System error",
+ ContainerNotExists: "Container does not exist",
+ ContainerNotStopped: "Container is not stopped",
+ ContainerNotRunning: "Container is not running",
+ ConsoleExists: "Console exists for process",
+ ContainerNotPaused: "Container is not paused",
+ NoProcessOps: "No process operations",
}
for code, expected := range codes {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go
index e67b001f..16235501 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go
@@ -6,7 +6,6 @@ import (
"encoding/json"
"fmt"
"os"
- "os/exec"
"path/filepath"
"regexp"
"runtime/debug"
@@ -23,41 +22,27 @@ import (
)
const (
- stateFilename = "state.json"
+ stateFilename = "state.json"
+ execFifoFilename = "exec.fifo"
)
var (
- idRegex = regexp.MustCompile(`^[\w-\.]+$`)
+ idRegex = regexp.MustCompile(`^[\w+-\.]+$`)
maxIdLen = 1024
)
// InitArgs returns an options func to configure a LinuxFactory with the
-// provided init arguments.
+// provided init binary path and arguments.
func InitArgs(args ...string) func(*LinuxFactory) error {
- return func(l *LinuxFactory) error {
- name := args[0]
- if filepath.Base(name) == name {
- if lp, err := exec.LookPath(name); err == nil {
- name = lp
+ return func(l *LinuxFactory) (err error) {
+ if len(args) > 0 {
+ // Resolve relative paths to ensure that its available
+ // after directory changes.
+ if args[0], err = filepath.Abs(args[0]); err != nil {
+ return newGenericError(err, ConfigInvalid)
}
- } else {
- abs, err := filepath.Abs(name)
- if err != nil {
- return err
- }
- name = abs
}
- l.InitPath = "/proc/self/exe"
- l.InitArgs = append([]string{name}, args[1:]...)
- return nil
- }
-}
-// InitPath returns an options func to configure a LinuxFactory with the
-// provided absolute path to the init binary and arguements.
-func InitPath(path string, args ...string) func(*LinuxFactory) error {
- return func(l *LinuxFactory) error {
- l.InitPath = path
l.InitArgs = args
return nil
}
@@ -102,6 +87,15 @@ func TmpfsRoot(l *LinuxFactory) error {
return nil
}
+// CriuPath returns an option func to configure a LinuxFactory with the
+// provided criupath
+func CriuPath(criupath string) func(*LinuxFactory) error {
+ return func(l *LinuxFactory) error {
+ l.CriuPath = criupath
+ return nil
+ }
+}
+
// New returns a linux based container factory based in the root directory and
// configures the factory with the provided option funcs.
func New(root string, options ...func(*LinuxFactory) error) (Factory, error) {
@@ -112,10 +106,10 @@ func New(root string, options ...func(*LinuxFactory) error) (Factory, error) {
}
l := &LinuxFactory{
Root: root,
+ InitArgs: []string{"/proc/self/exe", "init"},
Validator: validate.New(),
CriuPath: "criu",
}
- InitArgs(os.Args[0], "init")(l)
Cgroupfs(l)
for _, opt := range options {
if err := opt(l); err != nil {
@@ -130,9 +124,6 @@ type LinuxFactory struct {
// Root directory for the factory to store state.
Root string
- // InitPath is the absolute path to the init binary.
- InitPath string
-
// InitArgs are arguments for calling the init responsibilities for spawning
// a container.
InitArgs []string
@@ -158,20 +149,40 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err
if err := l.Validator.Validate(config); err != nil {
return nil, newGenericError(err, ConfigInvalid)
}
+ uid, err := config.HostUID()
+ if err != nil {
+ return nil, newGenericError(err, SystemError)
+ }
+ gid, err := config.HostGID()
+ if err != nil {
+ return nil, newGenericError(err, SystemError)
+ }
containerRoot := filepath.Join(l.Root, id)
if _, err := os.Stat(containerRoot); err == nil {
return nil, newGenericError(fmt.Errorf("container with id exists: %v", id), IdInUse)
} else if !os.IsNotExist(err) {
return nil, newGenericError(err, SystemError)
}
- if err := os.MkdirAll(containerRoot, 0700); err != nil {
+ if err := os.MkdirAll(containerRoot, 0711); err != nil {
+ return nil, newGenericError(err, SystemError)
+ }
+ if err := os.Chown(containerRoot, uid, gid); err != nil {
+ return nil, newGenericError(err, SystemError)
+ }
+ fifoName := filepath.Join(containerRoot, execFifoFilename)
+ oldMask := syscall.Umask(0000)
+ if err := syscall.Mkfifo(fifoName, 0622); err != nil {
+ syscall.Umask(oldMask)
+ return nil, newGenericError(err, SystemError)
+ }
+ syscall.Umask(oldMask)
+ if err := os.Chown(fifoName, uid, gid); err != nil {
return nil, newGenericError(err, SystemError)
}
c := &linuxContainer{
id: id,
root: containerRoot,
config: config,
- initPath: l.InitPath,
initArgs: l.InitArgs,
criuPath: l.CriuPath,
cgroupManager: l.NewCgroupsManager(config.Cgroups, nil),
@@ -185,7 +196,7 @@ func (l *LinuxFactory) Load(id string) (Container, error) {
return nil, newGenericError(fmt.Errorf("invalid root"), ConfigInvalid)
}
containerRoot := filepath.Join(l.Root, id)
- state, err := l.loadState(containerRoot)
+ state, err := l.loadState(containerRoot, id)
if err != nil {
return nil, err
}
@@ -195,17 +206,17 @@ func (l *LinuxFactory) Load(id string) (Container, error) {
fds: state.ExternalDescriptors,
}
c := &linuxContainer{
- initProcess: r,
- id: id,
- config: &state.Config,
- initPath: l.InitPath,
- initArgs: l.InitArgs,
- criuPath: l.CriuPath,
- cgroupManager: l.NewCgroupsManager(state.Config.Cgroups, state.CgroupPaths),
- root: containerRoot,
- created: state.Created,
+ initProcess: r,
+ initProcessStartTime: state.InitProcessStartTime,
+ id: id,
+ config: &state.Config,
+ initArgs: l.InitArgs,
+ criuPath: l.CriuPath,
+ cgroupManager: l.NewCgroupsManager(state.Config.Cgroups, state.CgroupPaths),
+ root: containerRoot,
+ created: state.Created,
}
- c.state = &createdState{c: c, s: Created}
+ c.state = &loadedState{c: c}
if err := c.refreshState(); err != nil {
return nil, err
}
@@ -219,55 +230,69 @@ func (l *LinuxFactory) Type() string {
// StartInitialization loads a container by opening the pipe fd from the parent to read the configuration and state
// This is a low level implementation detail of the reexec and should not be consumed externally
func (l *LinuxFactory) StartInitialization() (err error) {
- fdStr := os.Getenv("_LIBCONTAINER_INITPIPE")
- pipefd, err := strconv.Atoi(fdStr)
+ var (
+ pipefd, rootfd int
+ envInitPipe = os.Getenv("_LIBCONTAINER_INITPIPE")
+ envStateDir = os.Getenv("_LIBCONTAINER_STATEDIR")
+ )
+
+ // Get the INITPIPE.
+ pipefd, err = strconv.Atoi(envInitPipe)
if err != nil {
- return fmt.Errorf("error converting env var _LIBCONTAINER_INITPIPE(%q) to an int: %s", fdStr, err)
+ return fmt.Errorf("unable to convert _LIBCONTAINER_INITPIPE=%s to int: %s", envInitPipe, err)
}
+
var (
pipe = os.NewFile(uintptr(pipefd), "pipe")
it = initType(os.Getenv("_LIBCONTAINER_INITTYPE"))
)
+ defer pipe.Close()
+
+ // Only init processes have STATEDIR.
+ rootfd = -1
+ if it == initStandard {
+ rootfd, err = strconv.Atoi(envStateDir)
+ if err != nil {
+ return fmt.Errorf("unable to convert _LIBCONTAINER_STATEDIR=%s to int: %s", envStateDir, err)
+ }
+ }
+
// clear the current process's environment to clean any libcontainer
// specific env vars.
os.Clearenv()
- var i initer
+
defer func() {
// We have an error during the initialization of the container's init,
// send it back to the parent process in the form of an initError.
- // If container's init successed, syscall.Exec will not return, hence
- // this defer function will never be called.
- if _, ok := i.(*linuxStandardInit); ok {
- // Synchronisation only necessary for standard init.
- if err := utils.WriteJSON(pipe, syncT{procError}); err != nil {
- panic(err)
- }
+ if werr := utils.WriteJSON(pipe, syncT{procError}); werr != nil {
+ fmt.Fprintln(os.Stderr, err)
+ return
}
- if err := utils.WriteJSON(pipe, newSystemError(err)); err != nil {
- panic(err)
+ if werr := utils.WriteJSON(pipe, newSystemError(err)); werr != nil {
+ fmt.Fprintln(os.Stderr, err)
+ return
}
- // ensure that this pipe is always closed
- pipe.Close()
}()
-
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("panic from initialization: %v, %v", e, string(debug.Stack()))
}
}()
- i, err = newContainerInit(it, pipe)
+ i, err := newContainerInit(it, pipe, rootfd)
if err != nil {
return err
}
+
+ // If Init succeeds, syscall.Exec will not return, hence none of the defers will be called.
return i.Init()
}
-func (l *LinuxFactory) loadState(root string) (*State, error) {
+func (l *LinuxFactory) loadState(root, id string) (*State, error) {
f, err := os.Open(filepath.Join(root, stateFilename))
if err != nil {
if os.IsNotExist(err) {
- return nil, newGenericError(err, ContainerNotExists)
+ return nil, newGenericError(fmt.Errorf("container %q does not exist", id), ContainerNotExists)
}
return nil, newGenericError(err, SystemError)
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/generic_error.go b/vendor/github.com/opencontainers/runc/libcontainer/generic_error.go
index 3ed33da6..6e7de2fe 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/generic_error.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/generic_error.go
@@ -1,6 +1,7 @@
package libcontainer
import (
+ "fmt"
"io"
"text/template"
"time"
@@ -8,20 +9,6 @@ import (
"github.com/opencontainers/runc/libcontainer/stacktrace"
)
-type syncType uint8
-
-const (
- procReady syncType = iota
- procError
- procRun
- procHooks
- procResume
-)
-
-type syncT struct {
- Type syncType `json:"type"`
-}
-
var errorTemplate = template.Must(template.New("error").Parse(`Timestamp: {{.Timestamp}}
Code: {{.ECode}}
{{if .Message }}
@@ -51,14 +38,27 @@ func newGenericError(err error, c ErrorCode) Error {
}
func newSystemError(err error) Error {
- if le, ok := err.(Error); ok {
- return le
- }
+ return createSystemError(err, "")
+}
+
+func newSystemErrorWithCausef(err error, cause string, v ...interface{}) Error {
+ return createSystemError(err, fmt.Sprintf(cause, v...))
+}
+
+func newSystemErrorWithCause(err error, cause string) Error {
+ return createSystemError(err, cause)
+}
+
+// createSystemError creates the specified error with the correct number of
+// stack frames skipped. This is only to be called by the other functions for
+// formatting the error.
+func createSystemError(err error, cause string) Error {
gerr := &genericError{
Timestamp: time.Now(),
Err: err,
ECode: SystemError,
- Stack: stacktrace.Capture(1),
+ Cause: cause,
+ Stack: stacktrace.Capture(2),
}
if err != nil {
gerr.Message = err.Error()
@@ -70,12 +70,17 @@ type genericError struct {
Timestamp time.Time
ECode ErrorCode
Err error `json:"-"`
+ Cause string
Message string
Stack stacktrace.Stacktrace
}
func (e *genericError) Error() string {
- return e.Message
+ if e.Cause == "" {
+ return e.Message
+ }
+ frame := e.Stack.Frames[0]
+ return fmt.Sprintf("%s:%d: %s caused %q", frame.File, frame.Line, e.Cause, e.Message)
}
func (e *genericError) Code() ErrorCode {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/init_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/init_linux.go
index 0bde656e..8c7ef549 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/init_linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/init_linux.go
@@ -12,6 +12,7 @@ import (
"strconv"
"strings"
"syscall"
+ "unsafe"
"github.com/Sirupsen/logrus"
"github.com/opencontainers/runc/libcontainer/cgroups"
@@ -52,19 +53,21 @@ type initConfig struct {
AppArmorProfile string `json:"apparmor_profile"`
NoNewPrivileges bool `json:"no_new_privileges"`
User string `json:"user"`
+ AdditionalGroups []string `json:"additional_groups"`
Config *configs.Config `json:"config"`
- Console string `json:"console"`
Networks []*network `json:"network"`
PassedFilesCount int `json:"passed_files_count"`
ContainerId string `json:"containerid"`
Rlimits []configs.Rlimit `json:"rlimits"`
+ ExecFifoPath string `json:"start_pipe_path"`
+ CreateConsole bool `json:"create_console"`
}
type initer interface {
Init() error
}
-func newContainerInit(t initType, pipe *os.File) (initer, error) {
+func newContainerInit(t initType, pipe *os.File, stateDirFD int) (initer, error) {
var config *initConfig
if err := json.NewDecoder(pipe).Decode(&config); err != nil {
return nil, err
@@ -75,13 +78,15 @@ func newContainerInit(t initType, pipe *os.File) (initer, error) {
switch t {
case initSetns:
return &linuxSetnsInit{
+ pipe: pipe,
config: config,
}, nil
case initStandard:
return &linuxStandardInit{
- pipe: pipe,
- parentPid: syscall.Getppid(),
- config: config,
+ pipe: pipe,
+ parentPid: syscall.Getppid(),
+ config: config,
+ stateDirFD: stateDirFD,
}, nil
}
return nil, fmt.Errorf("unknown init type %q", t)
@@ -141,30 +146,85 @@ func finalizeNamespace(config *initConfig) error {
}
if config.Cwd != "" {
if err := syscall.Chdir(config.Cwd); err != nil {
- return err
+ return fmt.Errorf("chdir to cwd (%q) set in config.json failed: %v", config.Cwd, err)
}
}
return nil
}
+// setupConsole sets up the console from inside the container, and sends the
+// master pty fd to the config.Pipe (using cmsg). This is done to ensure that
+// consoles are scoped to a container properly (see runc#814 and the many
+// issues related to that). This has to be run *after* we've pivoted to the new
+// rootfs (and the users' configuration is entirely set up).
+func setupConsole(pipe *os.File, config *initConfig, mount bool) error {
+ // At this point, /dev/ptmx points to something that we would expect. We
+ // used to change the owner of the slave path, but since the /dev/pts mount
+ // can have gid=X set (at the users' option). So touching the owner of the
+ // slave PTY is not necessary, as the kernel will handle that for us. Note
+ // however, that setupUser (specifically fixStdioPermissions) *will* change
+ // the UID owner of the console to be the user the process will run as (so
+ // they can actually control their console).
+ console, err := newConsole()
+ if err != nil {
+ return err
+ }
+ // After we return from here, we don't need the console anymore.
+ defer console.Close()
+
+ linuxConsole, ok := console.(*linuxConsole)
+ if !ok {
+ return fmt.Errorf("failed to cast console to *linuxConsole")
+ }
+
+ // Mount the console inside our rootfs.
+ if mount {
+ if err := linuxConsole.mount(); err != nil {
+ return err
+ }
+ }
+
+ if err := writeSync(pipe, procConsole); err != nil {
+ return err
+ }
+
+ // We need to have a two-way synchronisation here. Though it might seem
+ // pointless, it's important to make sure that the sendmsg(2) payload
+ // doesn't get swallowed by an out-of-place read(2) [which happens if the
+ // syscalls get reordered so that sendmsg(2) is before the other side's
+ // read(2) of procConsole].
+ if err := readSync(pipe, procConsoleReq); err != nil {
+ return err
+ }
+
+ // While we can access console.master, using the API is a good idea.
+ if err := utils.SendFd(pipe, linuxConsole.File()); err != nil {
+ return err
+ }
+
+ // Make sure the other side received the fd.
+ if err := readSync(pipe, procConsoleAck); err != nil {
+ return err
+ }
+
+ // Now, dup over all the things.
+ return linuxConsole.dupStdio()
+}
+
// syncParentReady sends to the given pipe a JSON payload which indicates that
// the init is ready to Exec the child process. It then waits for the parent to
// indicate that it is cleared to Exec.
func syncParentReady(pipe io.ReadWriter) error {
// Tell parent.
- if err := utils.WriteJSON(pipe, syncT{procReady}); err != nil {
+ if err := writeSync(pipe, procReady); err != nil {
return err
}
+
// Wait for parent to give the all-clear.
- var procSync syncT
- if err := json.NewDecoder(pipe).Decode(&procSync); err != nil {
- if err == io.EOF {
- return fmt.Errorf("parent closed synchronisation channel")
- }
- if procSync.Type != procRun {
- return fmt.Errorf("invalid synchronisation flag from parent")
- }
+ if err := readSync(pipe, procRun); err != nil {
+ return err
}
+
return nil
}
@@ -173,19 +233,15 @@ func syncParentReady(pipe io.ReadWriter) error {
// indicate that it is cleared to resume.
func syncParentHooks(pipe io.ReadWriter) error {
// Tell parent.
- if err := utils.WriteJSON(pipe, syncT{procHooks}); err != nil {
+ if err := writeSync(pipe, procHooks); err != nil {
return err
}
+
// Wait for parent to give the all-clear.
- var procSync syncT
- if err := json.NewDecoder(pipe).Decode(&procSync); err != nil {
- if err == io.EOF {
- return fmt.Errorf("parent closed synchronisation channel")
- }
- if procSync.Type != procResume {
- return fmt.Errorf("invalid synchronisation flag from parent")
- }
+ if err := readSync(pipe, procResume); err != nil {
+ return err
}
+
return nil
}
@@ -211,8 +267,8 @@ func setupUser(config *initConfig) error {
}
var addGroups []int
- if len(config.Config.AdditionalGroups) > 0 {
- addGroups, err = user.GetAdditionalGroupsPath(config.Config.AdditionalGroups, groupPath)
+ if len(config.AdditionalGroups) > 0 {
+ addGroups, err = user.GetAdditionalGroupsPath(config.AdditionalGroups, groupPath)
if err != nil {
return err
}
@@ -259,11 +315,17 @@ func fixStdioPermissions(u *user.ExecUser) error {
if err := syscall.Fstat(int(fd), &s); err != nil {
return err
}
- // skip chown of /dev/null if it was used as one of the STDIO fds.
+ // Skip chown of /dev/null if it was used as one of the STDIO fds.
if s.Rdev == null.Rdev {
continue
}
- if err := syscall.Fchown(int(fd), u.Uid, u.Gid); err != nil {
+ // We only change the uid owner (as it is possible for the mount to
+ // prefer a different gid, and there's no reason for us to change it).
+ // The reason why we don't just leave the default uid=X mount setup is
+ // that users expect to be able to actually use their console. Without
+ // this code, you couldn't effectively run as a non-root user inside a
+ // container and also have a console set up.
+ if err := syscall.Fchown(int(fd), u.Uid, int(s.Gid)); err != nil {
return err
}
}
@@ -331,10 +393,51 @@ func setOomScoreAdj(oomScoreAdj int, pid int) error {
return ioutil.WriteFile(path, []byte(strconv.Itoa(oomScoreAdj)), 0600)
}
-// killCgroupProcesses freezes then iterates over all the processes inside the
-// manager's cgroups sending a SIGKILL to each process then waiting for them to
-// exit.
-func killCgroupProcesses(m cgroups.Manager) error {
+const _P_PID = 1
+
+type siginfo struct {
+ si_signo int32
+ si_errno int32
+ si_code int32
+ // below here is a union; si_pid is the only field we use
+ si_pid int32
+ // Pad to 128 bytes as detailed in blockUntilWaitable
+ pad [96]byte
+}
+
+// isWaitable returns true if the process has exited false otherwise.
+// Its based off blockUntilWaitable in src/os/wait_waitid.go
+func isWaitable(pid int) (bool, error) {
+ si := &siginfo{}
+ _, _, e := syscall.Syscall6(syscall.SYS_WAITID, _P_PID, uintptr(pid), uintptr(unsafe.Pointer(si)), syscall.WEXITED|syscall.WNOWAIT|syscall.WNOHANG, 0, 0)
+ if e != 0 {
+ return false, os.NewSyscallError("waitid", e)
+ }
+
+ return si.si_pid != 0, nil
+}
+
+// isNoChildren returns true if err represents a syscall.ECHILD false otherwise
+func isNoChildren(err error) bool {
+ switch err := err.(type) {
+ case syscall.Errno:
+ if err == syscall.ECHILD {
+ return true
+ }
+ case *os.SyscallError:
+ if err.Err == syscall.ECHILD {
+ return true
+ }
+ }
+ return false
+}
+
+// signalAllProcesses freezes then iterates over all the processes inside the
+// manager's cgroups sending the signal s to them.
+// If s is SIGKILL then it will wait for each process to exit.
+// For all other signals it will check if the process is ready to report its
+// exit status and only if it is will a wait be performed.
+func signalAllProcesses(m cgroups.Manager, s os.Signal) error {
var procs []*os.Process
if err := m.Freeze(configs.Frozen); err != nil {
logrus.Warn(err)
@@ -351,16 +454,31 @@ func killCgroupProcesses(m cgroups.Manager) error {
continue
}
procs = append(procs, p)
- if err := p.Kill(); err != nil {
+ if err := p.Signal(s); err != nil {
logrus.Warn(err)
}
}
if err := m.Freeze(configs.Thawed); err != nil {
logrus.Warn(err)
}
+
for _, p := range procs {
+ if s != syscall.SIGKILL {
+ if ok, err := isWaitable(p.Pid); err != nil {
+ if !isNoChildren(err) {
+ logrus.Warn("signalAllProcesses: ", p.Pid, err)
+ }
+ continue
+ } else if !ok {
+ // Not ready to report so don't wait
+ continue
+ }
+ }
+
if _, err := p.Wait(); err != nil {
- logrus.Warn(err)
+ if !isNoChildren(err) {
+ logrus.Warn("wait: ", err)
+ }
}
}
return nil
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/integration/checkpoint_test.go b/vendor/github.com/opencontainers/runc/libcontainer/integration/checkpoint_test.go
index a71c172a..7c5746b4 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/integration/checkpoint_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/integration/checkpoint_test.go
@@ -89,7 +89,7 @@ func TestCheckpoint(t *testing.T) {
Stdout: &stdout,
}
- err = container.Start(&pconfig)
+ err = container.Run(&pconfig)
stdinR.Close()
defer stdinW.Close()
if err != nil {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/integration/exec_test.go b/vendor/github.com/opencontainers/runc/libcontainer/integration/exec_test.go
index 45c64128..d9e3f5f1 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/integration/exec_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/integration/exec_test.go
@@ -2,6 +2,7 @@ package integration
import (
"bytes"
+ "encoding/json"
"fmt"
"io/ioutil"
"os"
@@ -38,12 +39,12 @@ func testExecPS(t *testing.T, userns bool) {
defer remove(rootfs)
config := newTemplateConfig(rootfs)
if userns {
- config.UidMappings = []configs.IDMap{{0, 0, 1000}}
- config.GidMappings = []configs.IDMap{{0, 0, 1000}}
+ config.UidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}}
+ config.GidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}}
config.Namespaces = append(config.Namespaces, configs.Namespace{Type: configs.NEWUSER})
}
- buffers, exitCode, err := runContainer(config, "", "ps")
+ buffers, exitCode, err := runContainer(config, "", "ps", "-o", "pid,user,comm")
if err != nil {
t.Fatalf("%s: %s", buffers, err)
}
@@ -180,8 +181,8 @@ func testRlimit(t *testing.T, userns bool) {
config := newTemplateConfig(rootfs)
if userns {
- config.UidMappings = []configs.IDMap{{0, 0, 1000}}
- config.GidMappings = []configs.IDMap{{0, 0, 1000}}
+ config.UidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}}
+ config.GidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}}
config.Namespaces = append(config.Namespaces, configs.Namespace{Type: configs.NEWUSER})
}
@@ -199,17 +200,6 @@ func testRlimit(t *testing.T, userns bool) {
}
}
-func newTestRoot() (string, error) {
- dir, err := ioutil.TempDir("", "libcontainer")
- if err != nil {
- return "", err
- }
- if err := os.MkdirAll(dir, 0700); err != nil {
- return "", err
- }
- return dir, nil
-}
-
func TestEnter(t *testing.T) {
if testing.Short() {
return
@@ -241,7 +231,7 @@ func TestEnter(t *testing.T) {
Stdin: stdinR,
Stdout: &stdout,
}
- err = container.Start(&pconfig)
+ err = container.Run(&pconfig)
stdinR.Close()
defer stdinW.Close()
ok(t, err)
@@ -259,7 +249,7 @@ func TestEnter(t *testing.T) {
pconfig2.Stdin = stdinR2
pconfig2.Stdout = &stdout2
- err = container.Start(&pconfig2)
+ err = container.Run(&pconfig2)
stdinR2.Close()
defer stdinW2.Close()
ok(t, err)
@@ -330,7 +320,7 @@ func TestProcessEnv(t *testing.T) {
Stdin: nil,
Stdout: &stdout,
}
- err = container.Start(&pconfig)
+ err = container.Run(&pconfig)
ok(t, err)
// Wait for process
@@ -378,7 +368,7 @@ func TestProcessCaps(t *testing.T) {
Stdin: nil,
Stdout: &stdout,
}
- err = container.Start(&pconfig)
+ err = container.Run(&pconfig)
ok(t, err)
// Wait for process
@@ -431,7 +421,6 @@ func TestAdditionalGroups(t *testing.T) {
defer remove(rootfs)
config := newTemplateConfig(rootfs)
- config.AdditionalGroups = []string{"plugdev", "audio"}
factory, err := libcontainer.New(root, libcontainer.Cgroupfs)
ok(t, err)
@@ -442,13 +431,14 @@ func TestAdditionalGroups(t *testing.T) {
var stdout bytes.Buffer
pconfig := libcontainer.Process{
- Cwd: "/",
- Args: []string{"sh", "-c", "id", "-Gn"},
- Env: standardEnvironment,
- Stdin: nil,
- Stdout: &stdout,
+ Cwd: "/",
+ Args: []string{"sh", "-c", "id", "-Gn"},
+ Env: standardEnvironment,
+ Stdin: nil,
+ Stdout: &stdout,
+ AdditionalGroups: []string{"plugdev", "audio"},
}
- err = container.Start(&pconfig)
+ err = container.Run(&pconfig)
ok(t, err)
// Wait for process
@@ -508,7 +498,7 @@ func testFreeze(t *testing.T, systemd bool) {
Env: standardEnvironment,
Stdin: stdinR,
}
- err = container.Start(pconfig)
+ err = container.Run(pconfig)
stdinR.Close()
defer stdinW.Close()
ok(t, err)
@@ -613,7 +603,7 @@ func testPids(t *testing.T, systemd bool) {
}
// Enforce a restrictive limit. 64 * /bin/true + 1 * shell should cause this
- // to fail reliabily.
+ // to fail reliability.
config.Cgroups.Resources.PidsLimit = 64
out, _, err := runContainer(config, "", "/bin/sh", "-c", `
/bin/true | /bin/true | /bin/true | /bin/true | /bin/true | /bin/true | bin/true | /bin/true |
@@ -719,7 +709,7 @@ func TestContainerState(t *testing.T) {
Env: standardEnvironment,
Stdin: stdinR,
}
- err = container.Start(p)
+ err = container.Run(p)
if err != nil {
t.Fatal(err)
}
@@ -772,7 +762,7 @@ func TestPassExtraFiles(t *testing.T) {
Stdin: nil,
Stdout: &stdout,
}
- err = container.Start(&process)
+ err = container.Run(&process)
if err != nil {
t.Fatal(err)
}
@@ -853,7 +843,7 @@ func TestMountCmds(t *testing.T) {
Args: []string{"sh", "-c", "env"},
Env: standardEnvironment,
}
- err = container.Start(&pconfig)
+ err = container.Run(&pconfig)
if err != nil {
t.Fatal(err)
}
@@ -902,7 +892,7 @@ func TestSysctl(t *testing.T) {
Stdin: nil,
Stdout: &stdout,
}
- err = container.Start(&pconfig)
+ err = container.Run(&pconfig)
ok(t, err)
// Wait for process
@@ -1042,7 +1032,7 @@ func TestOomScoreAdj(t *testing.T) {
Stdin: nil,
Stdout: &stdout,
}
- err = container.Start(&pconfig)
+ err = container.Run(&pconfig)
ok(t, err)
// Wait for process
@@ -1059,17 +1049,32 @@ func TestHook(t *testing.T) {
if testing.Short() {
return
}
- root, err := newTestRoot()
+
+ bundle, err := newTestBundle()
ok(t, err)
- defer os.RemoveAll(root)
+ defer remove(bundle)
rootfs, err := newRootfs()
ok(t, err)
defer remove(rootfs)
config := newTemplateConfig(rootfs)
- expectedBundlePath := "/path/to/bundle/path"
+ expectedBundlePath := bundle
config.Labels = append(config.Labels, fmt.Sprintf("bundle=%s", expectedBundlePath))
+
+ getRootfsFromBundle := func(bundle string) (string, error) {
+ f, err := os.Open(filepath.Join(bundle, "config.json"))
+ if err != nil {
+ return "", err
+ }
+
+ var config configs.Config
+ if err = json.NewDecoder(f).Decode(&config); err != nil {
+ return "", err
+ }
+ return config.Rootfs, nil
+ }
+
config.Hooks = &configs.Hooks{
Prestart: []configs.Hook{
configs.NewFunctionHook(func(s configs.HookState) error {
@@ -1077,7 +1082,11 @@ func TestHook(t *testing.T) {
t.Fatalf("Expected prestart hook bundlePath '%s'; got '%s'", expectedBundlePath, s.BundlePath)
}
- f, err := os.Create(filepath.Join(s.Root, "test"))
+ root, err := getRootfsFromBundle(s.BundlePath)
+ if err != nil {
+ return err
+ }
+ f, err := os.Create(filepath.Join(root, "test"))
if err != nil {
return err
}
@@ -1090,7 +1099,11 @@ func TestHook(t *testing.T) {
t.Fatalf("Expected poststart hook bundlePath '%s'; got '%s'", expectedBundlePath, s.BundlePath)
}
- return ioutil.WriteFile(filepath.Join(s.Root, "test"), []byte("hello world"), 0755)
+ root, err := getRootfsFromBundle(s.BundlePath)
+ if err != nil {
+ return err
+ }
+ return ioutil.WriteFile(filepath.Join(root, "test"), []byte("hello world"), 0755)
}),
},
Poststop: []configs.Hook{
@@ -1099,10 +1112,20 @@ func TestHook(t *testing.T) {
t.Fatalf("Expected poststop hook bundlePath '%s'; got '%s'", expectedBundlePath, s.BundlePath)
}
- return os.RemoveAll(filepath.Join(s.Root, "test"))
+ root, err := getRootfsFromBundle(s.BundlePath)
+ if err != nil {
+ return err
+ }
+ return os.RemoveAll(filepath.Join(root, "test"))
}),
},
}
+
+ // write config of json format into config.json under bundle
+ f, err := os.OpenFile(filepath.Join(bundle, "config.json"), os.O_CREATE|os.O_RDWR, 0644)
+ ok(t, err)
+ ok(t, json.NewEncoder(f).Encode(config))
+
container, err := factory.Create("test", config)
ok(t, err)
@@ -1114,7 +1137,7 @@ func TestHook(t *testing.T) {
Stdin: nil,
Stdout: &stdout,
}
- err = container.Start(&pconfig)
+ err = container.Run(&pconfig)
ok(t, err)
// Wait for process
@@ -1139,7 +1162,7 @@ func TestHook(t *testing.T) {
}
if err := container.Destroy(); err != nil {
- t.Fatalf("container destory %s", err)
+ t.Fatalf("container destroy %s", err)
}
fi, err := os.Stat(filepath.Join(rootfs, "test"))
if err == nil || !os.IsNotExist(err) {
@@ -1231,7 +1254,7 @@ func TestRootfsPropagationSlaveMount(t *testing.T) {
Stdin: stdinR,
}
- err = container.Start(pconfig)
+ err = container.Run(pconfig)
stdinR.Close()
defer stdinW.Close()
ok(t, err)
@@ -1260,7 +1283,7 @@ func TestRootfsPropagationSlaveMount(t *testing.T) {
Stdout: &stdout2,
}
- err = container.Start(pconfig2)
+ err = container.Run(pconfig2)
stdinR2.Close()
defer stdinW2.Close()
ok(t, err)
@@ -1348,7 +1371,7 @@ func TestRootfsPropagationSharedMount(t *testing.T) {
Stdin: stdinR,
}
- err = container.Start(pconfig)
+ err = container.Run(pconfig)
stdinR.Close()
defer stdinW.Close()
ok(t, err)
@@ -1380,7 +1403,7 @@ func TestRootfsPropagationSharedMount(t *testing.T) {
Capabilities: processCaps,
}
- err = container.Start(pconfig2)
+ err = container.Run(pconfig2)
stdinR2.Close()
defer stdinW2.Close()
ok(t, err)
@@ -1452,7 +1475,7 @@ func TestInitJoinPID(t *testing.T) {
Env: standardEnvironment,
Stdin: stdinR1,
}
- err = container1.Start(init1)
+ err = container1.Run(init1)
stdinR1.Close()
defer stdinW1.Close()
ok(t, err)
@@ -1462,7 +1485,7 @@ func TestInitJoinPID(t *testing.T) {
ok(t, err)
pidns1 := state1.NamespacePaths[configs.NEWPID]
- // Start a container inside the existing pidns but with different cgroups
+ // Run a container inside the existing pidns but with different cgroups
config2 := newTemplateConfig(rootfs)
config2.Namespaces.Add(configs.NEWPID, pidns1)
config2.Cgroups.Path = "integration/test2"
@@ -1478,7 +1501,7 @@ func TestInitJoinPID(t *testing.T) {
Env: standardEnvironment,
Stdin: stdinR2,
}
- err = container2.Start(init2)
+ err = container2.Run(init2)
stdinR2.Close()
defer stdinW2.Close()
ok(t, err)
@@ -1508,7 +1531,7 @@ func TestInitJoinPID(t *testing.T) {
Env: standardEnvironment,
Stdout: buffers.Stdout,
}
- err = container1.Start(ps)
+ err = container1.Run(ps)
ok(t, err)
waitProcess(ps, t)
@@ -1542,8 +1565,8 @@ func TestInitJoinNetworkAndUser(t *testing.T) {
// Execute a long-running container
config1 := newTemplateConfig(rootfs)
- config1.UidMappings = []configs.IDMap{{0, 0, 1000}}
- config1.GidMappings = []configs.IDMap{{0, 0, 1000}}
+ config1.UidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}}
+ config1.GidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}}
config1.Namespaces = append(config1.Namespaces, configs.Namespace{Type: configs.NEWUSER})
container1, err := newContainer(config1)
ok(t, err)
@@ -1557,7 +1580,7 @@ func TestInitJoinNetworkAndUser(t *testing.T) {
Env: standardEnvironment,
Stdin: stdinR1,
}
- err = container1.Start(init1)
+ err = container1.Run(init1)
stdinR1.Close()
defer stdinW1.Close()
ok(t, err)
@@ -1568,14 +1591,14 @@ func TestInitJoinNetworkAndUser(t *testing.T) {
netns1 := state1.NamespacePaths[configs.NEWNET]
userns1 := state1.NamespacePaths[configs.NEWUSER]
- // Start a container inside the existing pidns but with different cgroups
+ // Run a container inside the existing pidns but with different cgroups
rootfs2, err := newRootfs()
ok(t, err)
defer remove(rootfs2)
config2 := newTemplateConfig(rootfs2)
- config2.UidMappings = []configs.IDMap{{0, 0, 1000}}
- config2.GidMappings = []configs.IDMap{{0, 0, 1000}}
+ config2.UidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}}
+ config2.GidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}}
config2.Namespaces.Add(configs.NEWNET, netns1)
config2.Namespaces.Add(configs.NEWUSER, userns1)
config2.Cgroups.Path = "integration/test2"
@@ -1591,7 +1614,7 @@ func TestInitJoinNetworkAndUser(t *testing.T) {
Env: standardEnvironment,
Stdin: stdinR2,
}
- err = container2.Start(init2)
+ err = container2.Run(init2)
stdinR2.Close()
defer stdinW2.Close()
ok(t, err)
@@ -1622,3 +1645,52 @@ func TestInitJoinNetworkAndUser(t *testing.T) {
stdinW1.Close()
waitProcess(init1, t)
}
+
+func TestTmpfsCopyUp(t *testing.T) {
+ if testing.Short() {
+ return
+ }
+ root, err := newTestRoot()
+ ok(t, err)
+ defer os.RemoveAll(root)
+
+ rootfs, err := newRootfs()
+ ok(t, err)
+ defer remove(rootfs)
+
+ config := newTemplateConfig(rootfs)
+
+ config.Mounts = append(config.Mounts, &configs.Mount{
+ Source: "tmpfs",
+ Destination: "/etc",
+ Device: "tmpfs",
+ Extensions: configs.EXT_COPYUP,
+ })
+
+ factory, err := libcontainer.New(root, libcontainer.Cgroupfs)
+ ok(t, err)
+
+ container, err := factory.Create("test", config)
+ ok(t, err)
+ defer container.Destroy()
+
+ var stdout bytes.Buffer
+ pconfig := libcontainer.Process{
+ Args: []string{"ls", "/etc/passwd"},
+ Env: standardEnvironment,
+ Stdin: nil,
+ Stdout: &stdout,
+ }
+ err = container.Run(&pconfig)
+ ok(t, err)
+
+ // Wait for process
+ waitProcess(&pconfig, t)
+
+ outputLs := string(stdout.Bytes())
+
+ // Check that the ls output has /etc/passwd
+ if !strings.Contains(outputLs, "/etc/passwd") {
+ t.Fatalf("/etc/passwd not copied up as expected: %v", outputLs)
+ }
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/integration/execin_test.go b/vendor/github.com/opencontainers/runc/libcontainer/integration/execin_test.go
index da920ddb..f714f2df 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/integration/execin_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/integration/execin_test.go
@@ -36,7 +36,7 @@ func TestExecIn(t *testing.T) {
Env: standardEnvironment,
Stdin: stdinR,
}
- err = container.Start(process)
+ err = container.Run(process)
stdinR.Close()
defer stdinW.Close()
ok(t, err)
@@ -51,7 +51,7 @@ func TestExecIn(t *testing.T) {
Stderr: buffers.Stderr,
}
- err = container.Start(ps)
+ err = container.Run(ps)
ok(t, err)
waitProcess(ps, t)
stdinW.Close()
@@ -61,6 +61,9 @@ func TestExecIn(t *testing.T) {
if !strings.Contains(out, "cat") || !strings.Contains(out, "ps") {
t.Fatalf("unexpected running process, output %q", out)
}
+ if strings.Contains(out, "\r") {
+ t.Fatalf("unexpected carriage-return in output")
+ }
}
func TestExecInUsernsRlimit(t *testing.T) {
@@ -86,8 +89,8 @@ func testExecInRlimit(t *testing.T, userns bool) {
config := newTemplateConfig(rootfs)
if userns {
- config.UidMappings = []configs.IDMap{{0, 0, 1000}}
- config.GidMappings = []configs.IDMap{{0, 0, 1000}}
+ config.UidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}}
+ config.GidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}}
config.Namespaces = append(config.Namespaces, configs.Namespace{Type: configs.NEWUSER})
}
@@ -103,7 +106,7 @@ func testExecInRlimit(t *testing.T, userns bool) {
Env: standardEnvironment,
Stdin: stdinR,
}
- err = container.Start(process)
+ err = container.Run(process)
stdinR.Close()
defer stdinW.Close()
ok(t, err)
@@ -121,7 +124,7 @@ func testExecInRlimit(t *testing.T, userns bool) {
{Type: syscall.RLIMIT_NOFILE, Hard: 1026, Soft: 1026},
},
}
- err = container.Start(ps)
+ err = container.Run(ps)
ok(t, err)
waitProcess(ps, t)
@@ -134,6 +137,64 @@ func testExecInRlimit(t *testing.T, userns bool) {
}
}
+func TestExecInAdditionalGroups(t *testing.T) {
+ if testing.Short() {
+ return
+ }
+
+ rootfs, err := newRootfs()
+ ok(t, err)
+ defer remove(rootfs)
+
+ config := newTemplateConfig(rootfs)
+ container, err := newContainer(config)
+ ok(t, err)
+ defer container.Destroy()
+
+ // Execute a first process in the container
+ stdinR, stdinW, err := os.Pipe()
+ ok(t, err)
+ process := &libcontainer.Process{
+ Cwd: "/",
+ Args: []string{"cat"},
+ Env: standardEnvironment,
+ Stdin: stdinR,
+ }
+ err = container.Run(process)
+ stdinR.Close()
+ defer stdinW.Close()
+ ok(t, err)
+
+ var stdout bytes.Buffer
+ pconfig := libcontainer.Process{
+ Cwd: "/",
+ Args: []string{"sh", "-c", "id", "-Gn"},
+ Env: standardEnvironment,
+ Stdin: nil,
+ Stdout: &stdout,
+ AdditionalGroups: []string{"plugdev", "audio"},
+ }
+ err = container.Run(&pconfig)
+ ok(t, err)
+
+ // Wait for process
+ waitProcess(&pconfig, t)
+
+ stdinW.Close()
+ waitProcess(process, t)
+
+ outputGroups := string(stdout.Bytes())
+
+ // Check that the groups output has the groups that we specified
+ if !strings.Contains(outputGroups, "audio") {
+ t.Fatalf("Listed groups do not contain the audio group as expected: %v", outputGroups)
+ }
+
+ if !strings.Contains(outputGroups, "plugdev") {
+ t.Fatalf("Listed groups do not contain the plugdev group as expected: %v", outputGroups)
+ }
+}
+
func TestExecInError(t *testing.T) {
if testing.Short() {
return
@@ -155,7 +216,7 @@ func TestExecInError(t *testing.T) {
Env: standardEnvironment,
Stdin: stdinR,
}
- err = container.Start(process)
+ err = container.Run(process)
stdinR.Close()
defer func() {
stdinW.Close()
@@ -173,7 +234,7 @@ func TestExecInError(t *testing.T) {
Env: standardEnvironment,
Stdout: &out,
}
- err = container.Start(unexistent)
+ err = container.Run(unexistent)
if err == nil {
t.Fatal("Should be an error")
}
@@ -207,7 +268,7 @@ func TestExecInTTY(t *testing.T) {
Env: standardEnvironment,
Stdin: stdinR,
}
- err = container.Start(process)
+ err = container.Run(process)
stdinR.Close()
defer stdinW.Close()
ok(t, err)
@@ -218,15 +279,15 @@ func TestExecInTTY(t *testing.T) {
Args: []string{"ps"},
Env: standardEnvironment,
}
- console, err := ps.NewConsole(0)
+ err = container.Run(ps)
+ ok(t, err)
+ console, err := ps.GetConsole()
copy := make(chan struct{})
go func() {
io.Copy(&stdout, console)
close(copy)
}()
ok(t, err)
- err = container.Start(ps)
- ok(t, err)
select {
case <-time.After(5 * time.Second):
t.Fatal("Waiting for copy timed out")
@@ -238,9 +299,12 @@ func TestExecInTTY(t *testing.T) {
waitProcess(process, t)
out := stdout.String()
- if !strings.Contains(out, "cat") || !strings.Contains(string(out), "ps") {
+ if !strings.Contains(out, "cat") || !strings.Contains(out, "ps") {
t.Fatalf("unexpected running process, output %q", out)
}
+ if strings.Contains(out, "\r") {
+ t.Fatalf("unexpected carriage-return in output")
+ }
}
func TestExecInEnvironment(t *testing.T) {
@@ -264,7 +328,7 @@ func TestExecInEnvironment(t *testing.T) {
Env: standardEnvironment,
Stdin: stdinR,
}
- err = container.Start(process)
+ err = container.Run(process)
stdinR.Close()
defer stdinW.Close()
ok(t, err)
@@ -283,7 +347,7 @@ func TestExecInEnvironment(t *testing.T) {
Stdout: buffers.Stdout,
Stderr: buffers.Stderr,
}
- err = container.Start(process2)
+ err = container.Run(process2)
ok(t, err)
waitProcess(process2, t)
@@ -328,7 +392,7 @@ func TestExecinPassExtraFiles(t *testing.T) {
Env: standardEnvironment,
Stdin: stdinR,
}
- err = container.Start(process)
+ err = container.Run(process)
stdinR.Close()
defer stdinW.Close()
if err != nil {
@@ -346,7 +410,7 @@ func TestExecinPassExtraFiles(t *testing.T) {
Stdin: nil,
Stdout: &stdout,
}
- err = container.Start(inprocess)
+ err = container.Run(inprocess)
if err != nil {
t.Fatal(err)
}
@@ -401,7 +465,7 @@ func TestExecInOomScoreAdj(t *testing.T) {
Env: standardEnvironment,
Stdin: stdinR,
}
- err = container.Start(process)
+ err = container.Run(process)
stdinR.Close()
defer stdinW.Close()
ok(t, err)
@@ -415,7 +479,7 @@ func TestExecInOomScoreAdj(t *testing.T) {
Stdout: buffers.Stdout,
Stderr: buffers.Stderr,
}
- err = container.Start(ps)
+ err = container.Run(ps)
ok(t, err)
waitProcess(ps, t)
@@ -439,8 +503,8 @@ func TestExecInUserns(t *testing.T) {
ok(t, err)
defer remove(rootfs)
config := newTemplateConfig(rootfs)
- config.UidMappings = []configs.IDMap{{0, 0, 1000}}
- config.GidMappings = []configs.IDMap{{0, 0, 1000}}
+ config.UidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}}
+ config.GidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}}
config.Namespaces = append(config.Namespaces, configs.Namespace{Type: configs.NEWUSER})
container, err := newContainer(config)
ok(t, err)
@@ -456,7 +520,7 @@ func TestExecInUserns(t *testing.T) {
Env: standardEnvironment,
Stdin: stdinR,
}
- err = container.Start(process)
+ err = container.Run(process)
stdinR.Close()
defer stdinW.Close()
ok(t, err)
@@ -476,7 +540,7 @@ func TestExecInUserns(t *testing.T) {
Stdout: buffers.Stdout,
Stderr: os.Stderr,
}
- err = container.Start(process2)
+ err = container.Run(process2)
ok(t, err)
waitProcess(process2, t)
stdinW.Close()
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/integration/init_test.go b/vendor/github.com/opencontainers/runc/libcontainer/integration/init_test.go
index eaa6caf6..87b4f2ac 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/integration/init_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/integration/init_test.go
@@ -36,19 +36,19 @@ var (
func TestMain(m *testing.M) {
var (
err error
- ret int = 0
+ ret int
)
logrus.SetOutput(os.Stderr)
logrus.SetLevel(logrus.InfoLevel)
- factory, err = libcontainer.New(".", libcontainer.Cgroupfs)
+ factory, err = libcontainer.New("/run/libctTests", libcontainer.Cgroupfs)
if err != nil {
logrus.Error(err)
os.Exit(1)
}
if systemd.UseSystemd() {
- systemdFactory, err = libcontainer.New(".", libcontainer.SystemdCgroups)
+ systemdFactory, err = libcontainer.New("/run/libctTests", libcontainer.SystemdCgroups)
if err != nil {
logrus.Error(err)
os.Exit(1)
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/integration/seccomp_test.go b/vendor/github.com/opencontainers/runc/libcontainer/integration/seccomp_test.go
index 820773e6..055f887f 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/integration/seccomp_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/integration/seccomp_test.go
@@ -50,7 +50,7 @@ func TestSeccompDenyGetcwd(t *testing.T) {
Stderr: buffers.Stderr,
}
- err = container.Start(pwd)
+ err = container.Run(pwd)
if err != nil {
t.Fatal(err)
}
@@ -101,8 +101,8 @@ func TestSeccompPermitWriteConditional(t *testing.T) {
Args: []*configs.Arg{
{
Index: 0,
- Value: 1,
- Op: configs.GreaterThan,
+ Value: 2,
+ Op: configs.EqualTo,
},
},
},
@@ -125,7 +125,7 @@ func TestSeccompPermitWriteConditional(t *testing.T) {
Stderr: buffers.Stderr,
}
- err = container.Start(dmesg)
+ err = container.Run(dmesg)
if err != nil {
t.Fatal(err)
}
@@ -162,8 +162,8 @@ func TestSeccompDenyWriteConditional(t *testing.T) {
Args: []*configs.Arg{
{
Index: 0,
- Value: 1,
- Op: configs.GreaterThan,
+ Value: 2,
+ Op: configs.EqualTo,
},
},
},
@@ -186,7 +186,7 @@ func TestSeccompDenyWriteConditional(t *testing.T) {
Stderr: buffers.Stderr,
}
- err = container.Start(dmesg)
+ err = container.Run(dmesg)
if err != nil {
t.Fatal(err)
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/integration/template_test.go b/vendor/github.com/opencontainers/runc/libcontainer/integration/template_test.go
index f54a849a..a116ae30 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/integration/template_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/integration/template_test.go
@@ -20,6 +20,7 @@ const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NOD
// it uses a network strategy of just setting a loopback interface
// and the default setup for devices
func newTemplateConfig(rootfs string) *configs.Config {
+ allowAllDevices := false
return &configs.Config{
Rootfs: rootfs,
Capabilities: []string{
@@ -49,12 +50,13 @@ func newTemplateConfig(rootfs string) *configs.Config {
Path: "integration/test",
Resources: &configs.Resources{
MemorySwappiness: nil,
- AllowAllDevices: false,
+ AllowAllDevices: &allowAllDevices,
AllowedDevices: configs.DefaultAllowedDevices,
},
},
MaskPaths: []string{
"/proc/kcore",
+ "/sys/firmware",
},
ReadonlyPaths: []string{
"/proc/sys", "/proc/sysrq-trigger", "/proc/irq", "/proc/bus",
@@ -89,12 +91,15 @@ func newTemplateConfig(rootfs string) *configs.Config {
Data: "mode=1777,size=65536k",
Flags: defaultMountFlags,
},
- {
- Source: "mqueue",
- Destination: "/dev/mqueue",
- Device: "mqueue",
- Flags: defaultMountFlags,
- },
+ /*
+ CI is broken on the debian based kernels with this
+ {
+ Source: "mqueue",
+ Destination: "/dev/mqueue",
+ Device: "mqueue",
+ Flags: defaultMountFlags,
+ },
+ */
{
Source: "sysfs",
Destination: "/sys",
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/integration/utils_test.go b/vendor/github.com/opencontainers/runc/libcontainer/integration/utils_test.go
index e2ca10e0..74d94135 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/integration/utils_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/integration/utils_test.go
@@ -2,6 +2,8 @@ package integration
import (
"bytes"
+ "crypto/md5"
+ "encoding/hex"
"fmt"
"io/ioutil"
"os"
@@ -11,6 +13,7 @@ import (
"strings"
"syscall"
"testing"
+ "time"
"github.com/opencontainers/runc/libcontainer"
"github.com/opencontainers/runc/libcontainer/configs"
@@ -62,6 +65,28 @@ func waitProcess(p *libcontainer.Process, t *testing.T) {
}
}
+func newTestRoot() (string, error) {
+ dir, err := ioutil.TempDir("", "libcontainer")
+ if err != nil {
+ return "", err
+ }
+ if err := os.MkdirAll(dir, 0700); err != nil {
+ return "", err
+ }
+ return dir, nil
+}
+
+func newTestBundle() (string, error) {
+ dir, err := ioutil.TempDir("", "bundle")
+ if err != nil {
+ return "", err
+ }
+ if err := os.MkdirAll(dir, 0700); err != nil {
+ return "", err
+ }
+ return dir, nil
+}
+
// newRootfs creates a new tmp directory and copies the busybox root filesystem
func newRootfs() (string, error) {
dir, err := ioutil.TempDir("", "")
@@ -92,7 +117,9 @@ func copyBusybox(dest string) error {
}
func newContainer(config *configs.Config) (libcontainer.Container, error) {
- return newContainerWithName("testCT", config)
+ h := md5.New()
+ h.Write([]byte(time.Now().String()))
+ return newContainerWithName(hex.EncodeToString(h.Sum(nil)), config)
}
func newContainerWithName(name string, config *configs.Config) (libcontainer.Container, error) {
@@ -123,7 +150,7 @@ func runContainer(config *configs.Config, console string, args ...string) (buffe
Stderr: buffers.Stderr,
}
- err = container.Start(process)
+ err = container.Run(process)
if err != nil {
return buffers, -1, err
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/keys/keyctl.go b/vendor/github.com/opencontainers/runc/libcontainer/keys/keyctl.go
index c37ca213..8c90e56a 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/keys/keyctl.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/keys/keyctl.go
@@ -1,12 +1,12 @@
// +build linux
-package keyctl
+package keys
import (
"fmt"
- "syscall"
- "strings"
"strconv"
+ "strings"
+ "syscall"
"unsafe"
)
@@ -17,7 +17,7 @@ const KEYCTL_DESCRIBE = 6
type KeySerial uint32
func JoinSessionKeyring(name string) (KeySerial, error) {
- var _name *byte = nil
+ var _name *byte
var err error
if len(name) > 0 {
@@ -34,7 +34,7 @@ func JoinSessionKeyring(name string) (KeySerial, error) {
return KeySerial(sessKeyId), nil
}
-// modify permissions on a keyring by reading the current permissions,
+// ModKeyringPerm modifies permissions on a keyring by reading the current permissions,
// anding the bits with the given mask (clearing permissions) and setting
// additional permission bits
func ModKeyringPerm(ringId KeySerial, mask, setbits uint32) error {
@@ -64,4 +64,3 @@ func ModKeyringPerm(ringId KeySerial, mask, setbits uint32) error {
return nil
}
-
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/label/label.go b/vendor/github.com/opencontainers/runc/libcontainer/label/label.go
index 684bb41b..fddec463 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/label/label.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/label/label.go
@@ -9,6 +9,10 @@ func InitLabels(options []string) (string, string, error) {
return "", "", nil
}
+func GetROMountLabel() string {
+ return ""
+}
+
func GenLabels(options string) (string, string, error) {
return "", "", nil
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/label/label_selinux.go b/vendor/github.com/opencontainers/runc/libcontainer/label/label_selinux.go
index d443df4f..df9b2f3a 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/label/label_selinux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/label/label_selinux.go
@@ -55,6 +55,10 @@ func InitLabels(options []string) (string, string, error) {
return processLabel, mountLabel, nil
}
+func GetROMountLabel() string {
+ return selinux.GetROFileLabel()
+}
+
// DEPRECATED: The GenLabels function is only to be used during the transition to the official API.
func GenLabels(options string) (string, string, error) {
return InitLabels(strings.Fields(options))
@@ -107,7 +111,7 @@ func SetFileLabel(path string, fileLabel string) error {
return nil
}
-// Tell the kernel the label for all files to be created
+// SetFileCreateLabel tells the kernel the label for all files to be created
func SetFileCreateLabel(fileLabel string) error {
if selinux.SelinuxEnabled() {
return selinux.Setfscreatecon(fileLabel)
@@ -115,7 +119,7 @@ func SetFileCreateLabel(fileLabel string) error {
return nil
}
-// Change the label of path to the filelabel string.
+// Relabel changes the label of path to the filelabel string.
// It changes the MCS label to s0 if shared is true.
// This will allow all containers to share the content.
func Relabel(path string, fileLabel string, shared bool) error {
@@ -129,7 +133,7 @@ func Relabel(path string, fileLabel string, shared bool) error {
exclude_paths := map[string]bool{"/": true, "/usr": true, "/etc": true}
if exclude_paths[path] {
- return fmt.Errorf("Relabeling of %s is not allowed", path)
+ return fmt.Errorf("SELinux relabeling of %s is not allowed", path)
}
if shared {
@@ -137,7 +141,10 @@ func Relabel(path string, fileLabel string, shared bool) error {
c["level"] = "s0"
fileLabel = c.Get()
}
- return selinux.Chcon(path, fileLabel, true)
+ if err := selinux.Chcon(path, fileLabel, true); err != nil {
+ return fmt.Errorf("SELinux relabeling of %s is not allowed: %q", path, err)
+ }
+ return nil
}
// GetPidLabel will return the label of the process running with the specified pid
@@ -166,7 +173,7 @@ func UnreserveLabel(label string) error {
return nil
}
-// DupSecOpt takes an process label and returns security options that
+// DupSecOpt takes a process label and returns security options that
// can be used to set duplicate labels on future container processes
func DupSecOpt(src string) []string {
return selinux.DupSecOpt(src)
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/label/label_selinux_test.go b/vendor/github.com/opencontainers/runc/libcontainer/label/label_selinux_test.go
index aab89a8b..8956a70e 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/label/label_selinux_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/label/label_selinux_test.go
@@ -19,6 +19,10 @@ func TestInit(t *testing.T) {
t.Fatal(err)
}
testDisabled := []string{"disable"}
+ roMountLabel := GetROMountLabel()
+ if roMountLabel == "" {
+ t.Errorf("GetROMountLabel Failed")
+ }
plabel, mlabel, err = InitLabels(testDisabled)
if err != nil {
t.Log("InitLabels Disabled Failed")
@@ -26,7 +30,7 @@ func TestInit(t *testing.T) {
}
if plabel != "" {
t.Log("InitLabels Disabled Failed")
- t.Fatal()
+ t.FailNow()
}
testUser := []string{"user:user_u", "role:user_r", "type:user_t", "level:s0:c1,c15"}
plabel, mlabel, err = InitLabels(testUser)
@@ -51,39 +55,40 @@ func TestDuplicateLabel(t *testing.T) {
secopt := DupSecOpt("system_u:system_r:svirt_lxc_net_t:s0:c1,c2")
t.Log(secopt)
for _, opt := range secopt {
- con := strings.SplitN(opt, ":", 3)
- if len(con) != 3 || con[0] != "label" {
+ parts := strings.SplitN(opt, "=", 2)
+ if len(parts) != 2 || parts[0] != "label" {
t.Errorf("Invalid DupSecOpt return value")
continue
}
- if con[1] == "user" {
- if con[2] != "system_u" {
+ con := strings.SplitN(parts[1], ":", 2)
+ if con[0] == "user" {
+ if con[1] != "system_u" {
t.Errorf("DupSecOpt Failed user incorrect")
}
continue
}
- if con[1] == "role" {
- if con[2] != "system_r" {
+ if con[0] == "role" {
+ if con[1] != "system_r" {
t.Errorf("DupSecOpt Failed role incorrect")
}
continue
}
- if con[1] == "type" {
- if con[2] != "svirt_lxc_net_t" {
+ if con[0] == "type" {
+ if con[1] != "svirt_lxc_net_t" {
t.Errorf("DupSecOpt Failed type incorrect")
}
continue
}
- if con[1] == "level" {
- if con[2] != "s0:c1,c2" {
+ if con[0] == "level" {
+ if con[1] != "s0:c1,c2" {
t.Errorf("DupSecOpt Failed level incorrect")
}
continue
}
- t.Errorf("DupSecOpt Failed invalid field %q", con[1])
+ t.Errorf("DupSecOpt Failed invalid field %q", con[0])
}
secopt = DisableSecOpt()
- if secopt[0] != "label:disable" {
+ if secopt[0] != "label=disable" {
t.Errorf("DisableSecOpt Failed level incorrect")
}
}
@@ -93,24 +98,24 @@ func TestRelabel(t *testing.T) {
t.Fatal(err)
}
defer os.RemoveAll(testdir)
- label := "system_u:system_r:svirt_sandbox_file_t:s0:c1,c2"
+ label := "system_u:object_r:svirt_sandbox_file_t:s0:c1,c2"
if err := Relabel(testdir, "", true); err != nil {
- t.Fatal("Relabel with no label failed: %v", err)
+ t.Fatalf("Relabel with no label failed: %v", err)
}
if err := Relabel(testdir, label, true); err != nil {
- t.Fatal("Relabel shared failed: %v", err)
+ t.Fatalf("Relabel shared failed: %v", err)
}
if err := Relabel(testdir, label, false); err != nil {
- t.Fatal("Relabel unshared failed: %v", err)
+ t.Fatalf("Relabel unshared failed: %v", err)
}
if err := Relabel("/etc", label, false); err == nil {
- t.Fatal("Relabel /etc succeeded")
+ t.Fatalf("Relabel /etc succeeded")
}
if err := Relabel("/", label, false); err == nil {
- t.Fatal("Relabel / succeeded")
+ t.Fatalf("Relabel / succeeded")
}
if err := Relabel("/usr", label, false); err == nil {
- t.Fatal("Relabel /usr succeeded")
+ t.Fatalf("Relabel /usr succeeded")
}
}
@@ -131,13 +136,13 @@ func TestValidate(t *testing.T) {
func TestIsShared(t *testing.T) {
if shared := IsShared("Z"); shared {
- t.Fatal("Expected label `Z` to not be shared, got %v", shared)
+ t.Fatalf("Expected label `Z` to not be shared, got %v", shared)
}
if shared := IsShared("z"); !shared {
- t.Fatal("Expected label `z` to be shared, got %v", shared)
+ t.Fatalf("Expected label `z` to be shared, got %v", shared)
}
if shared := IsShared("Zz"); !shared {
- t.Fatal("Expected label `Zz` to be shared, got %v", shared)
+ t.Fatalf("Expected label `Zz` to be shared, got %v", shared)
}
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/message_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/message_linux.go
index 16630133..a189c724 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/message_linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/message_linux.go
@@ -11,13 +11,12 @@ import (
// list of known message types we want to send to bootstrap program
// The number is randomly chosen to not conflict with known netlink types
const (
- InitMsg uint16 = 62000
- CloneFlagsAttr uint16 = 27281
- ConsolePathAttr uint16 = 27282
- NsPathsAttr uint16 = 27283
- UidmapAttr uint16 = 27284
- GidmapAttr uint16 = 27285
- SetgroupAttr uint16 = 27286
+ InitMsg uint16 = 62000
+ CloneFlagsAttr uint16 = 27281
+ NsPathsAttr uint16 = 27282
+ UidmapAttr uint16 = 27283
+ GidmapAttr uint16 = 27284
+ SetgroupAttr uint16 = 27285
// When syscall.NLA_HDRLEN is in gccgo, take this out.
syscall_NLA_HDRLEN = (syscall.SizeofNlAttr + syscall.NLA_ALIGNTO - 1) & ^(syscall.NLA_ALIGNTO - 1)
)
@@ -27,7 +26,8 @@ type Int32msg struct {
Value uint32
}
-// int32msg has the following representation
+// Serialize serializes the message.
+// Int32msg has the following representation
// | nlattr len | nlattr type |
// | uint32 value |
func (msg *Int32msg) Serialize() []byte {
@@ -43,7 +43,7 @@ func (msg *Int32msg) Len() int {
return syscall_NLA_HDRLEN + 4
}
-// bytemsg has the following representation
+// Bytemsg has the following representation
// | nlattr len | nlattr type |
// | value | pad |
type Bytemsg struct {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/nsenter/README.md b/vendor/github.com/opencontainers/runc/libcontainer/nsenter/README.md
index d1a60ef9..57570137 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/nsenter/README.md
+++ b/vendor/github.com/opencontainers/runc/libcontainer/nsenter/README.md
@@ -10,16 +10,35 @@ The `nsenter` package will `import "C"` and it uses [cgo](https://golang.org/cmd
package. In cgo, if the import of "C" is immediately preceded by a comment, that comment,
called the preamble, is used as a header when compiling the C parts of the package.
So every time we import package `nsenter`, the C code function `nsexec()` would be
-called. And package `nsenter` is now only imported in Docker execdriver, so every time
-before we call `execdriver.Exec()`, that C code would run.
+called. And package `nsenter` is now only imported in `main_unix.go`, so every time
+before we call `cmd.Start` on linux, that C code would run.
+
+Because `nsexec()` must be run before the Go runtime in order to use the
+Linux kernel namespace, you must `import` this library into a package if
+you plan to use `libcontainer` directly. Otherwise Go will not execute
+the `nsexec()` constructor, which means that the re-exec will not cause
+the namespaces to be joined. You can import it like this:
+
+```go
+import _ "github.com/opencontainers/runc/libcontainer/nsenter"
+```
+
+`nsexec()` will first get the file descriptor number for the init pipe
+from the environment variable `_LIBCONTAINER_INITPIPE` (which was opened
+by the parent and kept open across the fork-exec of the `nsexec()` init
+process). The init pipe is used to read bootstrap data (namespace paths,
+clone flags, uid and gid mappings, and the console path) from the parent
+process. `nsexec()` will then call `setns(2)` to join the namespaces
+provided in the bootstrap data (if available), `clone(2)` a child process
+with the provided clone flags, update the user and group ID mappings, do
+some further miscellaneous setup steps, and then send the PID of the
+child process to the parent of the `nsexec()` "caller". Finally,
+the parent `nsexec()` will exit and the child `nsexec()` process will
+return to allow the Go runtime take over.
+
+NOTE: We do both `setns(2)` and `clone(2)` even if we don't have any
+CLONE_NEW* clone flags because we must fork a new process in order to
+enter the PID namespace.
-`nsexec()` will first check the environment variable `_LIBCONTAINER_INITPID`
-which will give the process of the container that should be joined. Namespaces fd will
-be found from `/proc/[pid]/ns` and set by `setns` syscall.
-And then get the pipe number from `_LIBCONTAINER_INITPIPE`, error message could
-be transfered through it. If tty is added, `_LIBCONTAINER_CONSOLE_PATH` will
-have value and start a console for output.
-Finally, `nsexec()` will clone a child process , exit the parent process and let
-the Go runtime take over.
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/nsenter/namespace.h b/vendor/github.com/opencontainers/runc/libcontainer/nsenter/namespace.h
new file mode 100644
index 00000000..9e9bdca0
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/nsenter/namespace.h
@@ -0,0 +1,32 @@
+#ifndef NSENTER_NAMESPACE_H
+#define NSENTER_NAMESPACE_H
+
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+#include
+
+/* All of these are taken from include/uapi/linux/sched.h */
+#ifndef CLONE_NEWNS
+# define CLONE_NEWNS 0x00020000 /* New mount namespace group */
+#endif
+#ifndef CLONE_NEWCGROUP
+# define CLONE_NEWCGROUP 0x02000000 /* New cgroup namespace */
+#endif
+#ifndef CLONE_NEWUTS
+# define CLONE_NEWUTS 0x04000000 /* New utsname namespace */
+#endif
+#ifndef CLONE_NEWIPC
+# define CLONE_NEWIPC 0x08000000 /* New ipc namespace */
+#endif
+#ifndef CLONE_NEWUSER
+# define CLONE_NEWUSER 0x10000000 /* New user namespace */
+#endif
+#ifndef CLONE_NEWPID
+# define CLONE_NEWPID 0x20000000 /* New pid namespace */
+#endif
+#ifndef CLONE_NEWNET
+# define CLONE_NEWNET 0x40000000 /* New network namespace */
+#endif
+
+#endif /* NSENTER_NAMESPACE_H */
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsenter_test.go b/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsenter_test.go
index 598e80b5..98b026f7 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsenter_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsenter_test.go
@@ -29,7 +29,7 @@ func TestNsenterValidPaths(t *testing.T) {
namespaces := []string{
// join pid ns of the current process
- fmt.Sprintf("/proc/%d/ns/pid", os.Getpid()),
+ fmt.Sprintf("pid:/proc/%d/ns/pid", os.Getpid()),
}
cmd := &exec.Cmd{
Path: os.Args[0],
@@ -87,7 +87,47 @@ func TestNsenterInvalidPaths(t *testing.T) {
namespaces := []string{
// join pid ns of the current process
- fmt.Sprintf("/proc/%d/ns/pid", -1),
+ fmt.Sprintf("pid:/proc/%d/ns/pid", -1),
+ }
+ cmd := &exec.Cmd{
+ Path: os.Args[0],
+ Args: args,
+ ExtraFiles: []*os.File{child},
+ Env: []string{"_LIBCONTAINER_INITPIPE=3"},
+ }
+
+ if err := cmd.Start(); err != nil {
+ t.Fatal(err)
+ }
+ // write cloneFlags
+ r := nl.NewNetlinkRequest(int(libcontainer.InitMsg), 0)
+ r.AddData(&libcontainer.Int32msg{
+ Type: libcontainer.CloneFlagsAttr,
+ Value: uint32(syscall.CLONE_NEWNET),
+ })
+ r.AddData(&libcontainer.Bytemsg{
+ Type: libcontainer.NsPathsAttr,
+ Value: []byte(strings.Join(namespaces, ",")),
+ })
+ if _, err := io.Copy(parent, bytes.NewReader(r.Serialize())); err != nil {
+ t.Fatal(err)
+ }
+
+ if err := cmd.Wait(); err == nil {
+ t.Fatalf("nsenter exits with a zero exit status")
+ }
+}
+
+func TestNsenterIncorrectPathType(t *testing.T) {
+ args := []string{"nsenter-exec"}
+ parent, child, err := newPipe()
+ if err != nil {
+ t.Fatalf("failed to create pipe %v", err)
+ }
+
+ namespaces := []string{
+ // join pid ns of the current process
+ fmt.Sprintf("net:/proc/%d/ns/pid", os.Getpid()),
}
cmd := &exec.Cmd{
Path: os.Args[0],
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c b/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c
index 8f37d6c1..7d15aeb5 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c
+++ b/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c
@@ -2,471 +2,758 @@
#include
#include
#include
-#include
-#include
-#include
+#include
#include
#include
#include
+#include
+#include
#include
#include
#include
+#include
#include
-#include
-#include
-#include
#include
-#include
-#include
+#include
+#include
+#include
+#include
+
+#include
+#include
#include
-// All arguments should be above the stack because it grows down
-struct clone_arg {
+/* Get all of the CLONE_NEW* flags. */
+#include "namespace.h"
+
+/* Synchronisation values. */
+enum sync_t {
+ SYNC_USERMAP_PLS = 0x40, /* Request parent to map our users. */
+ SYNC_USERMAP_ACK = 0x41, /* Mapping finished by the parent. */
+ SYNC_RECVPID_PLS = 0x42, /* Tell parent we're sending the PID. */
+ SYNC_RECVPID_ACK = 0x43, /* PID was correctly received by parent. */
+ SYNC_CHILD_READY = 0x44, /* The grandchild is ready to return. */
+
+ /* XXX: This doesn't help with segfaults and other such issues. */
+ SYNC_ERR = 0xFF, /* Fatal error, no turning back. The error code follows. */
+};
+
+/* longjmp() arguments. */
+#define JUMP_PARENT 0x00
+#define JUMP_CHILD 0xA0
+#define JUMP_INIT 0xA1
+
+/* JSON buffer. */
+#define JSON_MAX 4096
+
+/* Assume the stack grows down, so arguments should be above it. */
+struct clone_t {
/*
* Reserve some space for clone() to locate arguments
* and retcode in this place
*/
- char stack[4096] __attribute__((aligned(16)));
- char stack_ptr[0];
+ char stack[4096] __attribute__ ((aligned(16)));
+ char stack_ptr[0];
+
+ /* There's two children. This is used to execute the different code. */
jmp_buf *env;
+ int jmpval;
};
-struct nsenter_config {
+struct nlconfig_t {
+ char *data;
uint32_t cloneflags;
- char *uidmap;
- int uidmap_len;
- char *gidmap;
- int gidmap_len;
- uint8_t is_setgroup;
- int consolefd;
+ char *uidmap;
+ size_t uidmap_len;
+ char *gidmap;
+ size_t gidmap_len;
+ char *namespaces;
+ size_t namespaces_len;
+ uint8_t is_setgroup;
};
-// list of known message types we want to send to bootstrap program
-// These are defined in libcontainer/message_linux.go
-#define INIT_MSG 62000
-#define CLONE_FLAGS_ATTR 27281
-#define CONSOLE_PATH_ATTR 27282
-#define NS_PATHS_ATTR 27283
-#define UIDMAP_ATTR 27284
-#define GIDMAP_ATTR 27285
-#define SETGROUP_ATTR 27286
+/*
+ * List of netlink message types sent to us as part of bootstrapping the init.
+ * These constants are defined in libcontainer/message_linux.go.
+ */
+#define INIT_MSG 62000
+#define CLONE_FLAGS_ATTR 27281
+#define NS_PATHS_ATTR 27282
+#define UIDMAP_ATTR 27283
+#define GIDMAP_ATTR 27284
+#define SETGROUP_ATTR 27285
-// Use raw setns syscall for versions of glibc that don't include it
-// (namely glibc-2.12)
+/*
+ * Use the raw syscall for versions of glibc which don't include a function for
+ * it, namely (glibc 2.12).
+ */
#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 14
- #define _GNU_SOURCE
- #include "syscall.h"
- #if defined(__NR_setns) && !defined(SYS_setns)
- #define SYS_setns __NR_setns
- #endif
+# define _GNU_SOURCE
+# include "syscall.h"
+# if !defined(SYS_setns) && defined(__NR_setns)
+# define SYS_setns __NR_setns
+# endif
- #ifdef SYS_setns
- int setns(int fd, int nstype)
- {
- return syscall(SYS_setns, fd, nstype);
- }
- #endif
+#ifndef SYS_setns
+# error "setns(2) syscall not supported by glibc version"
#endif
-#define pr_perror(fmt, ...) \
- fprintf(stderr, "nsenter: " fmt ": %m\n", ##__VA_ARGS__)
-
-static int child_func(void *_arg)
+int setns(int fd, int nstype)
{
- struct clone_arg *arg = (struct clone_arg *)_arg;
- longjmp(*arg->env, 1);
+ return syscall(SYS_setns, fd, nstype);
}
+#endif
-static int clone_parent(jmp_buf *env, int flags) __attribute__((noinline));
-static int clone_parent(jmp_buf *env, int flags)
+/* XXX: This is ugly. */
+static int syncfd = -1;
+
+/* TODO(cyphar): Fix this so it correctly deals with syncT. */
+#define bail(fmt, ...) \
+ do { \
+ int ret = __COUNTER__ + 1; \
+ fprintf(stderr, "nsenter: " fmt ": %m\n", ##__VA_ARGS__); \
+ if (syncfd >= 0) { \
+ enum sync_t s = SYNC_ERR; \
+ if (write(syncfd, &s, sizeof(s)) != sizeof(s)) \
+ fprintf(stderr, "nsenter: failed: write(s)"); \
+ if (write(syncfd, &ret, sizeof(ret)) != sizeof(ret)) \
+ fprintf(stderr, "nsenter: failed: write(ret)"); \
+ } \
+ exit(ret); \
+ } while(0)
+
+static int write_file(char *data, size_t data_len, char *pathfmt, ...)
{
- struct clone_arg ca;
- int child;
+ int fd, len, ret = 0;
+ char path[PATH_MAX];
- ca.env = env;
- child = clone(child_func, ca.stack_ptr, CLONE_PARENT | SIGCHLD | flags,
- &ca);
- // On old kernels, CLONE_PARENT cannot work with CLONE_NEWPID,
- // unshare before clone to workaround this.
- if (child == -1 && errno == EINVAL) {
- if (unshare(flags)) {
- pr_perror("Unable to unshare namespaces");
- return -1;
- }
- child = clone(child_func, ca.stack_ptr, SIGCHLD | CLONE_PARENT,
- &ca);
+ va_list ap;
+ va_start(ap, pathfmt);
+ len = vsnprintf(path, PATH_MAX, pathfmt, ap);
+ va_end(ap);
+ if (len < 0)
+ return -1;
+
+ fd = open(path, O_RDWR);
+ if (fd < 0) {
+ ret = -1;
+ goto out;
}
- return child;
+
+ len = write(fd, data, data_len);
+ if (len != data_len) {
+ ret = -1;
+ goto out;
+ }
+
+out:
+ close(fd);
+ return ret;
}
-// get init pipe from the parent. It's used to read bootstrap data, and to
-// write pid to after nsexec finishes setting up the environment.
-static int get_init_pipe()
+enum policy_t {
+ SETGROUPS_DEFAULT = 0,
+ SETGROUPS_ALLOW,
+ SETGROUPS_DENY,
+};
+
+/* This *must* be called before we touch gid_map. */
+static void update_setgroups(int pid, enum policy_t setgroup)
{
- char buf[PATH_MAX];
- char *initpipe;
- int pipenum = -1;
+ char *policy;
+
+ switch (setgroup) {
+ case SETGROUPS_ALLOW:
+ policy = "allow";
+ break;
+ case SETGROUPS_DENY:
+ policy = "deny";
+ break;
+ case SETGROUPS_DEFAULT:
+ /* Nothing to do. */
+ return;
+ }
+
+ if (write_file(policy, strlen(policy), "/proc/%d/setgroups", pid) < 0) {
+ /*
+ * If the kernel is too old to support /proc/pid/setgroups,
+ * open(2) or write(2) will return ENOENT. This is fine.
+ */
+ if (errno != ENOENT)
+ bail("failed to write '%s' to /proc/%d/setgroups", policy, pid);
+ }
+}
+
+static void update_uidmap(int pid, char *map, int map_len)
+{
+ if (map == NULL || map_len <= 0)
+ return;
+
+ if (write_file(map, map_len, "/proc/%d/uid_map", pid) < 0)
+ bail("failed to update /proc/%d/uid_map", pid);
+}
+
+static void update_gidmap(int pid, char *map, int map_len)
+{
+ if (map == NULL || map_len <= 0)
+ return;
+
+ if (write_file(map, map_len, "/proc/%d/gid_map", pid) < 0)
+ bail("failed to update /proc/%d/gid_map", pid);
+}
+
+/* A dummy function that just jumps to the given jumpval. */
+static int child_func(void *arg) __attribute__ ((noinline));
+static int child_func(void *arg)
+{
+ struct clone_t *ca = (struct clone_t *)arg;
+ longjmp(*ca->env, ca->jmpval);
+}
+
+static int clone_parent(jmp_buf *env, int jmpval) __attribute__ ((noinline));
+static int clone_parent(jmp_buf *env, int jmpval)
+{
+ struct clone_t ca = {
+ .env = env,
+ .jmpval = jmpval,
+ };
+
+ return clone(child_func, ca.stack_ptr, CLONE_PARENT | SIGCHLD, &ca);
+}
+
+/*
+ * Gets the init pipe fd from the environment, which is used to read the
+ * bootstrap data and tell the parent what the new pid is after we finish
+ * setting up the environment.
+ */
+static int initpipe(void)
+{
+ int pipenum;
+ char *initpipe, *endptr;
initpipe = getenv("_LIBCONTAINER_INITPIPE");
- if (initpipe == NULL) {
+ if (initpipe == NULL || *initpipe == '\0')
return -1;
- }
- pipenum = atoi(initpipe);
- snprintf(buf, sizeof(buf), "%d", pipenum);
- if (strcmp(initpipe, buf)) {
- pr_perror("Unable to parse _LIBCONTAINER_INITPIPE");
- exit(1);
- }
+ pipenum = strtol(initpipe, &endptr, 10);
+ if (*endptr != '\0')
+ bail("unable to parse _LIBCONTAINER_INITPIPE");
return pipenum;
}
-// num_namespaces returns the number of additional namespaces to setns. The
-// argument is a comma-separated string of namespace paths.
-static int num_namespaces(char *nspaths)
+/* Returns the clone(2) flag for a namespace, given the name of a namespace. */
+static int nsflag(char *name)
{
- int i;
- int size = 0;
+ if (!strcmp(name, "cgroup"))
+ return CLONE_NEWCGROUP;
+ else if (!strcmp(name, "ipc"))
+ return CLONE_NEWIPC;
+ else if (!strcmp(name, "mnt"))
+ return CLONE_NEWNS;
+ else if (!strcmp(name, "net"))
+ return CLONE_NEWNET;
+ else if (!strcmp(name, "pid"))
+ return CLONE_NEWPID;
+ else if (!strcmp(name, "user"))
+ return CLONE_NEWUSER;
+ else if (!strcmp(name, "uts"))
+ return CLONE_NEWUTS;
- for (i = 0; nspaths[i]; i++) {
- if (nspaths[i] == ',') {
- size += 1;
- }
- }
-
- return size + 1;
+ /* If we don't recognise a name, fallback to 0. */
+ return 0;
}
static uint32_t readint32(char *buf)
{
- return *(uint32_t *)buf;
+ return *(uint32_t *) buf;
}
static uint8_t readint8(char *buf)
{
- return *(uint8_t *)buf;
+ return *(uint8_t *) buf;
}
-static void update_process_idmap(char *pathfmt, int pid, char *map, int map_len)
+static void nl_parse(int fd, struct nlconfig_t *config)
{
- char buf[PATH_MAX];
- int len;
- int fd;
+ size_t len, size;
+ struct nlmsghdr hdr;
+ char *data, *current;
- len = snprintf(buf, sizeof(buf), pathfmt, pid);
- if (len < 0) {
- pr_perror("failed to construct '%s' for %d", pathfmt, pid);
- exit(1);
- }
+ /* Retrieve the netlink header. */
+ len = read(fd, &hdr, NLMSG_HDRLEN);
+ if (len != NLMSG_HDRLEN)
+ bail("invalid netlink header length %lu", len);
- fd = open(buf, O_RDWR);
- if (fd == -1) {
- pr_perror("failed to open %s", buf);
- exit(1);
- }
+ if (hdr.nlmsg_type == NLMSG_ERROR)
+ bail("failed to read netlink message");
- len = write(fd, map, map_len);
- if (len == -1) {
- pr_perror("failed to write to %s", buf);
- close(fd);
- exit(1);
- } else if (len != map_len) {
- pr_perror("Failed to write data to %s (%d/%d)",
- buf, len, map_len);
- close(fd);
- exit(1);
- }
+ if (hdr.nlmsg_type != INIT_MSG)
+ bail("unexpected msg type %d", hdr.nlmsg_type);
- close(fd);
-}
+ /* Retrieve data. */
+ size = NLMSG_PAYLOAD(&hdr, 0);
+ current = data = malloc(size);
+ if (!data)
+ bail("failed to allocate %zu bytes of memory for nl_payload", size);
-static void update_process_uidmap(int pid, char *map, int map_len)
-{
- if ((map == NULL) || (map_len <= 0)) {
- return;
- }
+ len = read(fd, data, size);
+ if (len != size)
+ bail("failed to read netlink payload, %lu != %lu", len, size);
- update_process_idmap("/proc/%d/uid_map", pid, map, map_len);
-}
+ /* Parse the netlink payload. */
+ config->data = data;
+ while (current < data + size) {
+ struct nlattr *nlattr = (struct nlattr *)current;
+ size_t payload_len = nlattr->nla_len - NLA_HDRLEN;
-static void update_process_gidmap(int pid, uint8_t is_setgroup, char *map, int map_len)
-{
- if ((map == NULL) || (map_len <= 0)) {
- return;
- }
+ /* Advance to payload. */
+ current += NLA_HDRLEN;
- if (is_setgroup == 1) {
- int fd;
- int len;
- char buf[PATH_MAX];
-
- len = snprintf(buf, sizeof(buf), "/proc/%d/setgroups", pid);
- if (len < 0) {
- pr_perror("failed to get setgroups path for %d", pid);
- exit(1);
+ /* Handle payload. */
+ switch (nlattr->nla_type) {
+ case CLONE_FLAGS_ATTR:
+ config->cloneflags = readint32(current);
+ break;
+ case NS_PATHS_ATTR:
+ config->namespaces = current;
+ config->namespaces_len = payload_len;
+ break;
+ case UIDMAP_ATTR:
+ config->uidmap = current;
+ config->uidmap_len = payload_len;
+ break;
+ case GIDMAP_ATTR:
+ config->gidmap = current;
+ config->gidmap_len = payload_len;
+ break;
+ case SETGROUP_ATTR:
+ config->is_setgroup = readint8(current);
+ break;
+ default:
+ bail("unknown netlink message type %d", nlattr->nla_type);
}
- fd = open(buf, O_RDWR);
- if (fd == -1) {
- pr_perror("failed to open %s", buf);
- exit(1);
- }
- if (write(fd, "allow", 5) != 5) {
- // If the kernel is too old to support
- // /proc/PID/setgroups, write will return
- // ENOENT; this is OK.
- if (errno != ENOENT) {
- pr_perror("failed to write allow to %s", buf);
- close(fd);
- exit(1);
- }
- }
- close(fd);
+ current += NLA_ALIGN(payload_len);
}
-
- update_process_idmap("/proc/%d/gid_map", pid, map, map_len);
}
-
-static void start_child(int pipenum, jmp_buf *env, int syncpipe[2],
- struct nsenter_config *config)
+void nl_free(struct nlconfig_t *config)
{
- int len;
- int childpid;
- char buf[PATH_MAX];
- uint8_t syncbyte = 1;
-
- // We must fork to actually enter the PID namespace, use CLONE_PARENT
- // so the child can have the right parent, and we don't need to forward
- // the child's exit code or resend its death signal.
- childpid = clone_parent(env, config->cloneflags);
- if (childpid < 0) {
- pr_perror("Unable to fork");
- exit(1);
- }
-
- // update uid_map and gid_map for the child process if they
- // were provided
- update_process_uidmap(childpid, config->uidmap, config->uidmap_len);
- update_process_gidmap(childpid, config->is_setgroup, config->gidmap, config->gidmap_len);
-
- // Send the sync signal to the child
- close(syncpipe[0]);
- syncbyte = 1;
- if (write(syncpipe[1], &syncbyte, 1) != 1) {
- pr_perror("failed to write sync byte to child");
- exit(1);
- }
-
- // Send the child pid back to our parent
- len = snprintf(buf, sizeof(buf), "{ \"pid\" : %d }\n", childpid);
- if ((len < 0) || (write(pipenum, buf, len) != len)) {
- pr_perror("Unable to send a child pid");
- kill(childpid, SIGKILL);
- exit(1);
- }
-
- exit(0);
+ free(config->data);
}
-static struct nsenter_config process_nl_attributes(int pipenum, char *data, int data_size)
+void join_namespaces(char *nslist)
{
- struct nsenter_config config = {0};
- struct nlattr *nlattr;
- int payload_len;
- int start = 0;
+ int num = 0, i;
+ char *saveptr = NULL;
+ char *namespace = strtok_r(nslist, ",", &saveptr);
+ struct namespace_t {
+ int fd;
+ int ns;
+ char type[PATH_MAX];
+ char path[PATH_MAX];
+ } *namespaces = NULL;
- config.consolefd = -1;
- while (start < data_size) {
- nlattr = (struct nlattr *)(data + start);
- start += NLA_HDRLEN;
- payload_len = nlattr->nla_len - NLA_HDRLEN;
+ if (!namespace || !strlen(namespace) || !strlen(nslist))
+ bail("ns paths are empty");
- if (nlattr->nla_type == CLONE_FLAGS_ATTR) {
- config.cloneflags = readint32(data + start);
- } else if (nlattr->nla_type == CONSOLE_PATH_ATTR) {
- // get the console path before setns because it may
- // change mnt namespace
- config.consolefd = open(data + start, O_RDWR);
- if (config.consolefd < 0) {
- pr_perror("Failed to open console %s",
- data + start);
- exit(1);
- }
- } else if (nlattr->nla_type == NS_PATHS_ATTR) {
- // if custom namespaces are required, open all
- // descriptors and perform setns on them
- int i, j;
- int nslen = num_namespaces(data + start);
- int fds[nslen];
- char *nslist[nslen];
- char *ns;
- char *saveptr;
+ /*
+ * We have to open the file descriptors first, since after
+ * we join the mnt namespace we might no longer be able to
+ * access the paths.
+ */
+ do {
+ int fd;
+ char *path;
+ struct namespace_t *ns;
- for (i = 0; i < nslen; i++) {
- char *str = NULL;
+ /* Resize the namespace array. */
+ namespaces = realloc(namespaces, ++num * sizeof(struct namespace_t));
+ if (!namespaces)
+ bail("failed to reallocate namespace array");
+ ns = &namespaces[num - 1];
- if (i == 0) {
- str = data + start;
- }
- ns = strtok_r(str, ",", &saveptr);
- if (ns == NULL) {
- break;
- }
- fds[i] = open(ns, O_RDONLY);
- if (fds[i] == -1) {
- for (j = 0; j < i; j++) {
- close(fds[j]);
- }
- pr_perror("Failed to open %s", ns);
- exit(1);
- }
- nslist[i] = ns;
- }
+ /* Split 'ns:path'. */
+ path = strstr(namespace, ":");
+ if (!path)
+ bail("failed to parse %s", namespace);
+ *path++ = '\0';
- for (i = 0; i < nslen; i++) {
- if (setns(fds[i], 0) != 0) {
- pr_perror("Failed to setns to %s", nslist[i]);
- exit(1);
- }
- close(fds[i]);
- }
- } else if (nlattr->nla_type == UIDMAP_ATTR) {
- config.uidmap = data + start;
- config.uidmap_len = payload_len;
- } else if (nlattr->nla_type == GIDMAP_ATTR) {
- config.gidmap = data + start;
- config.gidmap_len = payload_len;
- } else if (nlattr->nla_type == SETGROUP_ATTR) {
- config.is_setgroup = readint8(data + start);
- } else {
- pr_perror("Unknown netlink message type %d",
- nlattr->nla_type);
- exit(1);
- }
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ bail("failed to open %s", path);
- start += NLA_ALIGN(payload_len);
+ ns->fd = fd;
+ ns->ns = nsflag(namespace);
+ strncpy(ns->path, path, PATH_MAX);
+ } while ((namespace = strtok_r(NULL, ",", &saveptr)) != NULL);
+
+ /*
+ * The ordering in which we join namespaces is important. We should
+ * always join the user namespace *first*. This is all guaranteed
+ * from the container_linux.go side of this, so we're just going to
+ * follow the order given to us.
+ */
+
+ for (i = 0; i < num; i++) {
+ struct namespace_t ns = namespaces[i];
+
+ if (setns(ns.fd, ns.ns) < 0)
+ bail("failed to setns to %s", ns.path);
+
+ close(ns.fd);
}
- return config;
+ free(namespaces);
}
void nsexec(void)
{
int pipenum;
+ jmp_buf env;
+ int syncpipe[2];
+ struct nlconfig_t config = {0};
- // If we don't have init pipe, then just return to the go routine,
- // we'll only have init pipe for start or exec
- pipenum = get_init_pipe();
- if (pipenum == -1) {
+ /*
+ * If we don't have an init pipe, just return to the go routine.
+ * We'll only get an init pipe for start or exec.
+ */
+ pipenum = initpipe();
+ if (pipenum == -1)
return;
+
+ /* make the process non-dumpable */
+ if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) != 0) {
+ bail("failed to set process as non-dumpable");
}
- // Retrieve the netlink header
- struct nlmsghdr nl_msg_hdr;
- int len;
+ /* Parse all of the netlink configuration. */
+ nl_parse(pipenum, &config);
- if ((len = read(pipenum, &nl_msg_hdr, NLMSG_HDRLEN)) != NLMSG_HDRLEN) {
- pr_perror("Invalid netlink header length %d", len);
- exit(1);
- }
+ /* Pipe so we can tell the child when we've finished setting up. */
+ if (socketpair(AF_LOCAL, SOCK_STREAM, 0, syncpipe) < 0)
+ bail("failed to setup sync pipe between parent and child");
- if (nl_msg_hdr.nlmsg_type == NLMSG_ERROR) {
- pr_perror("Failed to read netlink message");
- exit(1);
- }
+ /* TODO: Currently we aren't dealing with child deaths properly. */
- if (nl_msg_hdr.nlmsg_type != INIT_MSG) {
- pr_perror("Unexpected msg type %d", nl_msg_hdr.nlmsg_type);
- exit(1);
- }
+ /*
+ * Okay, so this is quite annoying.
+ *
+ * In order for this unsharing code to be more extensible we need to split
+ * up unshare(CLONE_NEWUSER) and clone() in various ways. The ideal case
+ * would be if we did clone(CLONE_NEWUSER) and the other namespaces
+ * separately, but because of SELinux issues we cannot really do that. But
+ * we cannot just dump the namespace flags into clone(...) because several
+ * usecases (such as rootless containers) require more granularity around
+ * the namespace setup. In addition, some older kernels had issues where
+ * CLONE_NEWUSER wasn't handled before other namespaces (but we cannot
+ * handle this while also dealing with SELinux so we choose SELinux support
+ * over broken kernel support).
+ *
+ * However, if we unshare(2) the user namespace *before* we clone(2), then
+ * all hell breaks loose.
+ *
+ * The parent no longer has permissions to do many things (unshare(2) drops
+ * all capabilities in your old namespace), and the container cannot be set
+ * up to have more than one {uid,gid} mapping. This is obviously less than
+ * ideal. In order to fix this, we have to first clone(2) and then unshare.
+ *
+ * Unfortunately, it's not as simple as that. We have to fork to enter the
+ * PID namespace (the PID namespace only applies to children). Since we'll
+ * have to double-fork, this clone_parent() call won't be able to get the
+ * PID of the _actual_ init process (without doing more synchronisation than
+ * I can deal with at the moment). So we'll just get the parent to send it
+ * for us, the only job of this process is to update
+ * /proc/pid/{setgroups,uid_map,gid_map}.
+ *
+ * And as a result of the above, we also need to setns(2) in the first child
+ * because if we join a PID namespace in the topmost parent then our child
+ * will be in that namespace (and it will not be able to give us a PID value
+ * that makes sense without resorting to sending things with cmsg).
+ *
+ * This also deals with an older issue caused by dumping cloneflags into
+ * clone(2): On old kernels, CLONE_PARENT didn't work with CLONE_NEWPID, so
+ * we have to unshare(2) before clone(2) in order to do this. This was fixed
+ * in upstream commit 1f7f4dde5c945f41a7abc2285be43d918029ecc5, and was
+ * introduced by 40a0d32d1eaffe6aac7324ca92604b6b3977eb0e. As far as we're
+ * aware, the last mainline kernel which had this bug was Linux 3.12.
+ * However, we cannot comment on which kernels the broken patch was
+ * backported to.
+ *
+ * -- Aleksa "what has my life come to?" Sarai
+ */
- // Retrieve data
- int nl_total_size = NLMSG_PAYLOAD(&nl_msg_hdr, 0);
- char data[nl_total_size];
+ switch (setjmp(env)) {
+ /*
+ * Stage 0: We're in the parent. Our job is just to create a new child
+ * (stage 1: JUMP_CHILD) process and write its uid_map and
+ * gid_map. That process will go on to create a new process, then
+ * it will send us its PID which we will send to the bootstrap
+ * process.
+ */
+ case JUMP_PARENT: {
+ int len, ready = 0;
+ pid_t child;
+ char buf[JSON_MAX];
- if ((len = read(pipenum, data, nl_total_size)) != nl_total_size) {
- pr_perror("Failed to read netlink payload, %d != %d", len,
- nl_total_size);
- exit(1);
- }
+ /* For debugging. */
+ prctl(PR_SET_NAME, (unsigned long) "runc:[0:PARENT]", 0, 0, 0);
- jmp_buf env;
- int syncpipe[2] = {-1, -1};
- struct nsenter_config config = process_nl_attributes(pipenum,
- data, nl_total_size);
+ /* Start the process of getting a container. */
+ child = clone_parent(&env, JUMP_CHILD);
+ if (child < 0)
+ bail("unable to fork: child_func");
- // required clone_flags to be passed
- if (config.cloneflags == -1) {
- pr_perror("Missing clone_flags");
- exit(1);
- }
- // prepare sync pipe between parent and child. We need this to let the
- // child know that the parent has finished setting up
- if (pipe(syncpipe) != 0) {
- pr_perror("Failed to setup sync pipe between parent and child");
- exit(1);
- }
+ /*
+ * State machine for synchronisation with the children.
+ *
+ * Father only return when both child and grandchild are
+ * ready, so we can receive all possible error codes
+ * generated by children.
+ */
+ while (ready < 2) {
+ enum sync_t s;
- if (setjmp(env) == 1) {
- // Child
- uint8_t s = 0;
- int consolefd = config.consolefd;
+ /* This doesn't need to be global, we're in the parent. */
+ int syncfd = syncpipe[1];
- // close the writing side of pipe
- close(syncpipe[1]);
+ if (read(syncfd, &s, sizeof(s)) != sizeof(s))
+ bail("failed to sync with child: next state");
- // sync with parent
- if ((read(syncpipe[0], &s, 1) != 1) || (s != 1)) {
- pr_perror("Failed to read sync byte from parent");
- exit(1);
- }
+ switch (s) {
+ case SYNC_ERR: {
+ /* We have to mirror the error code of the child. */
+ int ret;
- if (setsid() == -1) {
- pr_perror("setsid failed");
- exit(1);
- }
+ if (read(syncfd, &ret, sizeof(ret)) != sizeof(ret))
+ bail("failed to sync with child: read(error code)");
- if (setuid(0) == -1) {
- pr_perror("setuid failed");
- exit(1);
- }
+ exit(ret);
+ }
+ break;
+ case SYNC_USERMAP_PLS:
+ /* Enable setgroups(2) if we've been asked to. */
+ if (config.is_setgroup)
+ update_setgroups(child, SETGROUPS_ALLOW);
- if (setgid(0) == -1) {
- pr_perror("setgid failed");
- exit(1);
- }
-
- if (setgroups(0, NULL) == -1) {
- pr_perror("setgroups failed");
- exit(1);
- }
+ /* Set up mappings. */
+ update_uidmap(child, config.uidmap, config.uidmap_len);
+ update_gidmap(child, config.gidmap, config.gidmap_len);
- if (consolefd != -1) {
- if (ioctl(consolefd, TIOCSCTTY, 0) == -1) {
- pr_perror("ioctl TIOCSCTTY failed");
- exit(1);
+ s = SYNC_USERMAP_ACK;
+ if (write(syncfd, &s, sizeof(s)) != sizeof(s)) {
+ kill(child, SIGKILL);
+ bail("failed to sync with child: write(SYNC_USERMAP_ACK)");
+ }
+ break;
+ case SYNC_USERMAP_ACK:
+ /* We should _never_ receive acks. */
+ kill(child, SIGKILL);
+ bail("failed to sync with child: unexpected SYNC_USERMAP_ACK");
+ break;
+ case SYNC_RECVPID_PLS: {
+ pid_t old = child;
+
+ /* Get the init_func pid. */
+ if (read(syncfd, &child, sizeof(child)) != sizeof(child)) {
+ kill(old, SIGKILL);
+ bail("failed to sync with child: read(childpid)");
+ }
+
+ /* Send ACK. */
+ s = SYNC_RECVPID_ACK;
+ if (write(syncfd, &s, sizeof(s)) != sizeof(s)) {
+ kill(old, SIGKILL);
+ kill(child, SIGKILL);
+ bail("failed to sync with child: write(SYNC_RECVPID_ACK)");
+ }
+ }
+
+ ready++;
+ break;
+ case SYNC_RECVPID_ACK:
+ /* We should _never_ receive acks. */
+ kill(child, SIGKILL);
+ bail("failed to sync with child: unexpected SYNC_RECVPID_ACK");
+ break;
+ case SYNC_CHILD_READY:
+ ready++;
+ break;
+ default:
+ bail("unexpected sync value");
+ break;
+ }
}
- if (dup3(consolefd, STDIN_FILENO, 0) != STDIN_FILENO) {
- pr_perror("Failed to dup stdin");
- exit(1);
+
+ /* Send the init_func pid back to our parent. */
+ len = snprintf(buf, JSON_MAX, "{\"pid\": %d}\n", child);
+ if (len < 0) {
+ kill(child, SIGKILL);
+ bail("unable to generate JSON for child pid");
}
- if (dup3(consolefd, STDOUT_FILENO, 0) != STDOUT_FILENO) {
- pr_perror("Failed to dup stdout");
- exit(1);
- }
- if (dup3(consolefd, STDERR_FILENO, 0) != STDERR_FILENO) {
- pr_perror("Failed to dup stderr");
- exit(1);
+ if (write(pipenum, buf, len) != len) {
+ kill(child, SIGKILL);
+ bail("unable to send child pid to bootstrapper");
}
+
+ exit(0);
}
- // Finish executing, let the Go runtime take over.
- return;
+ /*
+ * Stage 1: We're in the first child process. Our job is to join any
+ * provided namespaces in the netlink payload and unshare all
+ * of the requested namespaces. If we've been asked to
+ * CLONE_NEWUSER, we will ask our parent (stage 0) to set up
+ * our user mappings for us. Then, we create a new child
+ * (stage 2: JUMP_INIT) for PID namespace. We then send the
+ * child's PID to our parent (stage 0).
+ */
+ case JUMP_CHILD: {
+ pid_t child;
+ enum sync_t s;
+
+ /* We're in a child and thus need to tell the parent if we die. */
+ syncfd = syncpipe[0];
+
+ /* For debugging. */
+ prctl(PR_SET_NAME, (unsigned long) "runc:[1:CHILD]", 0, 0, 0);
+
+ /*
+ * We need to setns first. We cannot do this earlier (in stage 0)
+ * because of the fact that we forked to get here (the PID of
+ * [stage 2: JUMP_INIT]) would be meaningless). We could send it
+ * using cmsg(3) but that's just annoying.
+ */
+ if (config.namespaces)
+ join_namespaces(config.namespaces);
+
+ /*
+ * Unshare all of the namespaces. Now, it should be noted that this
+ * ordering might break in the future (especially with rootless
+ * containers). But for now, it's not possible to split this into
+ * CLONE_NEWUSER + [the rest] because of some RHEL SELinux issues.
+ *
+ * Note that we don't merge this with clone() because there were
+ * some old kernel versions where clone(CLONE_PARENT | CLONE_NEWPID)
+ * was broken, so we'll just do it the long way anyway.
+ */
+ if (unshare(config.cloneflags) < 0)
+ bail("failed to unshare namespaces");
+
+ /*
+ * Deal with user namespaces first. They are quite special, as they
+ * affect our ability to unshare other namespaces and are used as
+ * context for privilege checks.
+ */
+ if (config.cloneflags & CLONE_NEWUSER) {
+ /*
+ * We don't have the privileges to do any mapping here (see the
+ * clone_parent rant). So signal our parent to hook us up.
+ */
+
+ s = SYNC_USERMAP_PLS;
+ if (write(syncfd, &s, sizeof(s)) != sizeof(s))
+ bail("failed to sync with parent: write(SYNC_USERMAP_PLS)");
+
+ /* ... wait for mapping ... */
+
+ if (read(syncfd, &s, sizeof(s)) != sizeof(s))
+ bail("failed to sync with parent: read(SYNC_USERMAP_ACK)");
+ if (s != SYNC_USERMAP_ACK)
+ bail("failed to sync with parent: SYNC_USERMAP_ACK: got %u", s);
+ }
+
+ /*
+ * TODO: What about non-namespace clone flags that we're dropping here?
+ *
+ * We fork again because of PID namespace, setns(2) or unshare(2) don't
+ * change the PID namespace of the calling process, because doing so
+ * would change the caller's idea of its own PID (as reported by getpid()),
+ * which would break many applications and libraries, so we must fork
+ * to actually enter the new PID namespace.
+ */
+ child = clone_parent(&env, JUMP_INIT);
+ if (child < 0)
+ bail("unable to fork: init_func");
+
+ /* Send the child to our parent, which knows what it's doing. */
+ s = SYNC_RECVPID_PLS;
+ if (write(syncfd, &s, sizeof(s)) != sizeof(s)) {
+ kill(child, SIGKILL);
+ bail("failed to sync with parent: write(SYNC_RECVPID_PLS)");
+ }
+ if (write(syncfd, &child, sizeof(child)) != sizeof(child)) {
+ kill(child, SIGKILL);
+ bail("failed to sync with parent: write(childpid)");
+ }
+
+ /* ... wait for parent to get the pid ... */
+
+ if (read(syncfd, &s, sizeof(s)) != sizeof(s)) {
+ kill(child, SIGKILL);
+ bail("failed to sync with parent: read(SYNC_RECVPID_ACK)");
+ }
+ if (s != SYNC_RECVPID_ACK) {
+ kill(child, SIGKILL);
+ bail("failed to sync with parent: SYNC_RECVPID_ACK: got %u", s);
+ }
+
+ /* Our work is done. [Stage 2: JUMP_INIT] is doing the rest of the work. */
+ exit(0);
+ }
+
+ /*
+ * Stage 2: We're the final child process, and the only process that will
+ * actually return to the Go runtime. Our job is to just do the
+ * final cleanup steps and then return to the Go runtime to allow
+ * init_linux.go to run.
+ */
+ case JUMP_INIT: {
+ /*
+ * We're inside the child now, having jumped from the
+ * start_child() code after forking in the parent.
+ */
+ enum sync_t s;
+
+ /* We're in a child and thus need to tell the parent if we die. */
+ syncfd = syncpipe[0];
+
+ /* For debugging. */
+ prctl(PR_SET_NAME, (unsigned long) "runc:[2:INIT]", 0, 0, 0);
+
+ if (setsid() < 0)
+ bail("setsid failed");
+
+ if (setuid(0) < 0)
+ bail("setuid failed");
+
+ if (setgid(0) < 0)
+ bail("setgid failed");
+
+ if (setgroups(0, NULL) < 0)
+ bail("setgroups failed");
+
+ s = SYNC_CHILD_READY;
+ if (write(syncfd, &s, sizeof(s)) != sizeof(s))
+ bail("failed to sync with patent: write(SYNC_CHILD_READY)");
+
+ /* Close sync pipes. */
+ close(syncpipe[0]);
+ close(syncpipe[1]);
+
+ /* Free netlink data. */
+ nl_free(&config);
+
+ /* Finish executing, let the Go runtime take over. */
+ return;
+ }
+ default:
+ bail("unexpected jump value");
+ break;
}
- // Parent
- start_child(pipenum, &env, syncpipe, &config);
+ /* Should never be reached. */
+ bail("should never be reached");
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/process.go b/vendor/github.com/opencontainers/runc/libcontainer/process.go
index 91e8ef56..859d2708 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/process.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/process.go
@@ -28,6 +28,10 @@ type Process struct {
// local to the container's user and group configuration.
User string
+ // AdditionalGroups specifies the gids that should be added to supplementary groups
+ // in addition to those that the user belongs to.
+ AdditionalGroups []string
+
// Cwd will change the processes current working directory inside the container's rootfs.
Cwd string
@@ -43,8 +47,9 @@ type Process struct {
// ExtraFiles specifies additional open files to be inherited by the container
ExtraFiles []*os.File
- // consolePath is the path to the console allocated to the container.
- consolePath string
+ // consoleChan provides the masterfd console.
+ // TODO: Make this persistent in Process.
+ consoleChan chan *os.File
// Capabilities specify the capabilities to keep when executing the process inside the container
// All capabilities not specified will be dropped from the processes capability mask
@@ -101,21 +106,14 @@ type IO struct {
Stderr io.ReadCloser
}
-// NewConsole creates new console for process and returns it
-func (p *Process) NewConsole(rootuid int) (Console, error) {
- console, err := NewConsole(rootuid, rootuid)
- if err != nil {
- return nil, err
+func (p *Process) GetConsole() (Console, error) {
+ consoleFd, ok := <-p.consoleChan
+ if !ok {
+ return nil, fmt.Errorf("failed to get console from process")
}
- p.consolePath = console.Path()
- return console, nil
-}
-// ConsoleFromPath sets the process's console with the path provided
-func (p *Process) ConsoleFromPath(path string) error {
- if p.consolePath != "" {
- return newGenericError(fmt.Errorf("console path already exists for process"), ConsoleExists)
- }
- p.consolePath = path
- return nil
+ // TODO: Fix this so that it used the console API.
+ return &linuxConsole{
+ master: consoleFd,
+ }, nil
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go
index 1a2ee0bc..50e90757 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go
@@ -32,7 +32,7 @@ type parentProcess interface {
// wait waits on the process returning the process state.
wait() (*os.ProcessState, error)
- // startTime return's the process start time.
+ // startTime returns the process start time.
startTime() (string, error)
signal(os.Signal) error
@@ -70,47 +70,74 @@ func (p *setnsProcess) start() (err error) {
err = p.cmd.Start()
p.childPipe.Close()
if err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "starting setns process")
}
if p.bootstrapData != nil {
if _, err := io.Copy(p.parentPipe, p.bootstrapData); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "copying bootstrap data to pipe")
}
}
if err = p.execSetns(); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "executing setns process")
}
if len(p.cgroupPaths) > 0 {
if err := cgroups.EnterPid(p.cgroupPaths, p.pid()); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCausef(err, "adding pid %d to cgroups", p.pid())
}
}
// set oom_score_adj
if err := setOomScoreAdj(p.config.Config.OomScoreAdj, p.pid()); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "setting oom score")
}
// set rlimits, this has to be done here because we lose permissions
// to raise the limits once we enter a user-namespace
if err := setupRlimits(p.config.Rlimits, p.pid()); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "setting rlimits for process")
}
if err := utils.WriteJSON(p.parentPipe, p.config); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "writing config to pipe")
}
+ ierr := parseSync(p.parentPipe, func(sync *syncT) error {
+ switch sync.Type {
+ case procConsole:
+ if err := writeSync(p.parentPipe, procConsoleReq); err != nil {
+ return newSystemErrorWithCause(err, "writing syncT 'request fd'")
+ }
+
+ masterFile, err := utils.RecvFd(p.parentPipe)
+ if err != nil {
+ return newSystemErrorWithCause(err, "getting master pty from child pipe")
+ }
+
+ if p.process.consoleChan == nil {
+ // TODO: Don't panic here, do something more sane.
+ panic("consoleChan is nil")
+ }
+ p.process.consoleChan <- masterFile
+
+ if err := writeSync(p.parentPipe, procConsoleAck); err != nil {
+ return newSystemErrorWithCause(err, "writing syncT 'ack fd'")
+ }
+ case procReady:
+ // This shouldn't happen.
+ panic("unexpected procReady in setns")
+ case procHooks:
+ // This shouldn't happen.
+ panic("unexpected procHooks in setns")
+ default:
+ return newSystemError(fmt.Errorf("invalid JSON payload from child"))
+ }
+ return nil
+ })
+
if err := syscall.Shutdown(int(p.parentPipe.Fd()), syscall.SHUT_WR); err != nil {
- return newSystemError(err)
- }
- // wait for the child process to fully complete and receive an error message
- // if one was encoutered
- var ierr *genericError
- if err := json.NewDecoder(p.parentPipe).Decode(&ierr); err != nil && err != io.EOF {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "calling shutdown on init pipe")
}
// Must be done after Shutdown so the child will exit and we can wait for it.
if ierr != nil {
p.wait()
- return newSystemError(ierr)
+ return ierr
}
return nil
}
@@ -123,7 +150,7 @@ func (p *setnsProcess) execSetns() error {
status, err := p.cmd.Process.Wait()
if err != nil {
p.cmd.Wait()
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "waiting on setns process to finish")
}
if !status.Success() {
p.cmd.Wait()
@@ -132,7 +159,7 @@ func (p *setnsProcess) execSetns() error {
var pid *pid
if err := json.NewDecoder(p.parentPipe).Decode(&pid); err != nil {
p.cmd.Wait()
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "reading pid from init pipe")
}
process, err := os.FindProcess(pid.Pid)
if err != nil {
@@ -144,7 +171,7 @@ func (p *setnsProcess) execSetns() error {
}
// terminate sends a SIGKILL to the forked process for the setns routine then waits to
-// avoid the process becomming a zombie.
+// avoid the process becoming a zombie.
func (p *setnsProcess) terminate() error {
if p.cmd.Process == nil {
return nil
@@ -186,6 +213,7 @@ type initProcess struct {
process *Process
bootstrapData io.Reader
sharePidns bool
+ rootDir *os.File
}
func (p *initProcess) pid() int {
@@ -221,6 +249,7 @@ func (p *initProcess) execSetns() error {
return err
}
p.cmd.Process = process
+ p.process.ops = p
return nil
}
@@ -229,28 +258,29 @@ func (p *initProcess) start() error {
err := p.cmd.Start()
p.process.ops = p
p.childPipe.Close()
+ p.rootDir.Close()
if err != nil {
p.process.ops = nil
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "starting init process command")
}
if _, err := io.Copy(p.parentPipe, p.bootstrapData); err != nil {
return err
}
if err := p.execSetns(); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "running exec setns process for init")
}
// Save the standard descriptor names before the container process
// can potentially move them (e.g., via dup2()). If we don't do this now,
// we won't know at checkpoint time which file descriptor to look up.
fds, err := getPipeFds(p.pid())
if err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCausef(err, "getting pipe fds for pid %d", p.pid())
}
p.setExternalDescriptors(fds)
// Do this before syncing with child so that no children
// can escape the cgroup
if err := p.manager.Apply(p.pid()); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "applying cgroup configuration for process")
}
defer func() {
if err != nil {
@@ -259,60 +289,69 @@ func (p *initProcess) start() error {
}
}()
if err := p.createNetworkInterfaces(); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "creating network interfaces")
}
if err := p.sendConfig(); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "sending config to init process")
}
var (
- procSync syncT
sentRun bool
sentResume bool
- ierr *genericError
)
- dec := json.NewDecoder(p.parentPipe)
-loop:
- for {
- if err := dec.Decode(&procSync); err != nil {
- if err == io.EOF {
- break loop
+ ierr := parseSync(p.parentPipe, func(sync *syncT) error {
+ switch sync.Type {
+ case procConsole:
+ if err := writeSync(p.parentPipe, procConsoleReq); err != nil {
+ return newSystemErrorWithCause(err, "writing syncT 'request fd'")
+ }
+
+ masterFile, err := utils.RecvFd(p.parentPipe)
+ if err != nil {
+ return newSystemErrorWithCause(err, "getting master pty from child pipe")
+ }
+
+ if p.process.consoleChan == nil {
+ // TODO: Don't panic here, do something more sane.
+ panic("consoleChan is nil")
+ }
+ p.process.consoleChan <- masterFile
+
+ if err := writeSync(p.parentPipe, procConsoleAck); err != nil {
+ return newSystemErrorWithCause(err, "writing syncT 'ack fd'")
}
- return newSystemError(err)
- }
- switch procSync.Type {
case procReady:
if err := p.manager.Set(p.config.Config); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "setting cgroup config for ready process")
}
// set oom_score_adj
if err := setOomScoreAdj(p.config.Config.OomScoreAdj, p.pid()); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "setting oom score for ready process")
}
// set rlimits, this has to be done here because we lose permissions
// to raise the limits once we enter a user-namespace
if err := setupRlimits(p.config.Rlimits, p.pid()); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "setting rlimits for ready process")
}
// call prestart hooks
if !p.config.Config.Namespaces.Contains(configs.NEWNS) {
if p.config.Config.Hooks != nil {
s := configs.HookState{
- Version: p.container.config.Version,
- ID: p.container.id,
- Pid: p.pid(),
- Root: p.config.Config.Rootfs,
+ Version: p.container.config.Version,
+ ID: p.container.id,
+ Pid: p.pid(),
+ BundlePath: utils.SearchLabels(p.config.Config.Labels, "bundle"),
}
- for _, hook := range p.config.Config.Hooks.Prestart {
+ for i, hook := range p.config.Config.Hooks.Prestart {
if err := hook.Run(s); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCausef(err, "running prestart hook %d", i)
}
}
}
}
// Sync with child.
- if err := utils.WriteJSON(p.parentPipe, syncT{procRun}); err != nil {
- return newSystemError(err)
+ if err := writeSync(p.parentPipe, procRun); err != nil {
+ return newSystemErrorWithCause(err, "writing syncT 'run'")
}
sentRun = true
case procHooks:
@@ -321,48 +360,40 @@ loop:
Version: p.container.config.Version,
ID: p.container.id,
Pid: p.pid(),
- Root: p.config.Config.Rootfs,
BundlePath: utils.SearchLabels(p.config.Config.Labels, "bundle"),
}
- for _, hook := range p.config.Config.Hooks.Prestart {
+ for i, hook := range p.config.Config.Hooks.Prestart {
if err := hook.Run(s); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCausef(err, "running prestart hook %d", i)
}
}
}
// Sync with child.
- if err := utils.WriteJSON(p.parentPipe, syncT{procResume}); err != nil {
- return newSystemError(err)
+ if err := writeSync(p.parentPipe, procResume); err != nil {
+ return newSystemErrorWithCause(err, "writing syncT 'resume'")
}
sentResume = true
- case procError:
- // wait for the child process to fully complete and receive an error message
- // if one was encoutered
- if err := dec.Decode(&ierr); err != nil && err != io.EOF {
- return newSystemError(err)
- }
- if ierr != nil {
- break loop
- }
- // Programmer error.
- panic("No error following JSON procError payload.")
default:
- return newSystemError(fmt.Errorf("invalid JSON synchronisation payload from child"))
+ return newSystemError(fmt.Errorf("invalid JSON payload from child"))
}
- }
+
+ return nil
+ })
+
if !sentRun {
- return newSystemError(fmt.Errorf("could not synchronise with container process: %v", ierr))
+ return newSystemErrorWithCause(ierr, "container init")
}
if p.config.Config.Namespaces.Contains(configs.NEWNS) && !sentResume {
return newSystemError(fmt.Errorf("could not synchronise after executing prestart hooks with container process"))
}
if err := syscall.Shutdown(int(p.parentPipe.Fd()), syscall.SHUT_WR); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "shutting down init pipe")
}
+
// Must be done after Shutdown so the child will exit and we can wait for it.
if ierr != nil {
p.wait()
- return newSystemError(ierr)
+ return ierr
}
return nil
}
@@ -374,7 +405,7 @@ func (p *initProcess) wait() (*os.ProcessState, error) {
}
// we should kill all processes in cgroup when init is died if we use host PID namespace
if p.sharePidns {
- killCgroupProcesses(p.manager)
+ signalAllProcesses(p.manager, syscall.SIGKILL)
}
return p.cmd.ProcessState, nil
}
@@ -435,6 +466,8 @@ func getPipeFds(pid int) ([]string, error) {
dirPath := filepath.Join("/proc", strconv.Itoa(pid), "/fd")
for i := 0; i < 3; i++ {
+ // XXX: This breaks if the path is not a valid symlink (which can
+ // happen in certain particularly unlucky mount namespace setups).
f := filepath.Join(dirPath, strconv.Itoa(i))
target, err := os.Readlink(f)
if err != nil {
@@ -445,9 +478,11 @@ func getPipeFds(pid int) ([]string, error) {
return fds, nil
}
-// InitializeIO creates pipes for use with the process's STDIO
-// and returns the opposite side for each
-func (p *Process) InitializeIO(rootuid int) (i *IO, err error) {
+// InitializeIO creates pipes for use with the process's stdio and returns the
+// opposite side for each. Do not use this if you want to have a pseudoterminal
+// set up for you by libcontainer (TODO: fix that too).
+// TODO: This is mostly unnecessary, and should be handled by clients.
+func (p *Process) InitializeIO(rootuid, rootgid int) (i *IO, err error) {
var fds []uintptr
i = &IO{}
// cleanup in case of an error
@@ -479,7 +514,7 @@ func (p *Process) InitializeIO(rootuid int) (i *IO, err error) {
p.Stderr, i.Stderr = w, r
// change ownership of the pipes incase we are in a user namespace
for _, fd := range fds {
- if err := syscall.Fchown(int(fd), rootuid, rootuid); err != nil {
+ if err := syscall.Fchown(int(fd), rootuid, rootgid); err != nil {
return nil, err
}
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go
index 4aa4cbd5..2472c71d 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go
@@ -16,6 +16,7 @@ import (
"github.com/docker/docker/pkg/mount"
"github.com/docker/docker/pkg/symlink"
+ "github.com/mrunalp/fileutils"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/label"
@@ -25,51 +26,56 @@ import (
const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV
-// setupDev returns true if /dev needs to be set up.
+// needsSetupDev returns true if /dev needs to be set up.
func needsSetupDev(config *configs.Config) bool {
for _, m := range config.Mounts {
- if m.Device == "bind" && (m.Destination == "/dev" || m.Destination == "/dev/") {
+ if m.Device == "bind" && libcontainerUtils.CleanPath(m.Destination) == "/dev" {
return false
}
}
return true
}
-// setupRootfs sets up the devices, mount points, and filesystems for use inside a
-// new mount namespace.
-func setupRootfs(config *configs.Config, console *linuxConsole, pipe io.ReadWriter) (err error) {
+// prepareRootfs sets up the devices, mount points, and filesystems for use
+// inside a new mount namespace. It doesn't set anything as ro or pivot_root,
+// because console setup happens inside the caller. You must call
+// finalizeRootfs in order to finish the rootfs setup.
+func prepareRootfs(pipe io.ReadWriter, config *configs.Config) (err error) {
if err := prepareRoot(config); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "preparing rootfs")
}
setupDev := needsSetupDev(config)
for _, m := range config.Mounts {
for _, precmd := range m.PremountCmds {
if err := mountCmd(precmd); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "running premount command")
}
}
+
if err := mountToRootfs(m, config.Rootfs, config.MountLabel); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCausef(err, "mounting %q to rootfs %q at %q", m.Source, config.Rootfs, m.Destination)
}
for _, postcmd := range m.PostmountCmds {
if err := mountCmd(postcmd); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "running postmount command")
}
}
}
+
if setupDev {
if err := createDevices(config); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "creating device nodes")
}
- if err := setupPtmx(config, console); err != nil {
- return newSystemError(err)
+ if err := setupPtmx(config); err != nil {
+ return newSystemErrorWithCause(err, "setting up ptmx")
}
if err := setupDevSymlinks(config.Rootfs); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "setting up /dev symlinks")
}
}
+
// Signal the parent to run the pre-start hooks.
// The hooks are run after the mounts are setup, but before we switch to the new
// root, so that the old root is still available in the hooks for any mount
@@ -77,52 +83,70 @@ func setupRootfs(config *configs.Config, console *linuxConsole, pipe io.ReadWrit
if err := syncParentHooks(pipe); err != nil {
return err
}
+
+ // The reason these operations are done here rather than in finalizeRootfs
+ // is because the console-handling code gets quite sticky if we have to set
+ // up the console before doing the pivot_root(2). This is because the
+ // Console API has to also work with the ExecIn case, which means that the
+ // API must be able to deal with being inside as well as outside the
+ // container. It's just cleaner to do this here (at the expense of the
+ // operation not being perfectly split).
+
if err := syscall.Chdir(config.Rootfs); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCausef(err, "changing dir to %q", config.Rootfs)
}
+
if config.NoPivotRoot {
err = msMoveRoot(config.Rootfs)
} else {
- err = pivotRoot(config.Rootfs, config.PivotDir)
+ err = pivotRoot(config.Rootfs)
}
if err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "jailing process inside rootfs")
}
+
if setupDev {
if err := reOpenDevNull(); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "reopening /dev/null inside container")
}
}
- // remount dev as ro if specifed
+
+ return nil
+}
+
+// finalizeRootfs actually switches the root of the process and sets anything
+// to ro if necessary. You must call prepareRootfs first.
+func finalizeRootfs(config *configs.Config) (err error) {
+ // remount dev as ro if specified
for _, m := range config.Mounts {
- if m.Destination == "/dev" {
- if m.Flags&syscall.MS_RDONLY != 0 {
- if err := remountReadonly(m.Destination); err != nil {
- return newSystemError(err)
+ if libcontainerUtils.CleanPath(m.Destination) == "/dev" {
+ if m.Flags&syscall.MS_RDONLY == syscall.MS_RDONLY {
+ if err := remountReadonly(m); err != nil {
+ return newSystemErrorWithCausef(err, "remounting %q as readonly", m.Destination)
}
}
break
}
}
+
// set rootfs ( / ) as readonly
if config.Readonlyfs {
if err := setReadonly(); err != nil {
- return newSystemError(err)
+ return newSystemErrorWithCause(err, "setting rootfs as readonly")
}
}
+
syscall.Umask(0022)
return nil
}
func mountCmd(cmd configs.Command) error {
-
command := exec.Command(cmd.Path, cmd.Args[:]...)
command.Env = cmd.Env
command.Dir = cmd.Dir
if out, err := command.CombinedOutput(); err != nil {
return fmt.Errorf("%#v failed: %s: %v", cmd, string(out), err)
}
-
return nil
}
@@ -154,15 +178,41 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
}
return nil
case "tmpfs":
+ copyUp := m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP
+ tmpDir := ""
stat, err := os.Stat(dest)
if err != nil {
if err := os.MkdirAll(dest, 0755); err != nil {
return err
}
}
+ if copyUp {
+ tmpDir, err = ioutil.TempDir("/tmp", "runctmpdir")
+ if err != nil {
+ return newSystemErrorWithCause(err, "tmpcopyup: failed to create tmpdir")
+ }
+ defer os.RemoveAll(tmpDir)
+ m.Destination = tmpDir
+ }
if err := mountPropagate(m, rootfs, mountLabel); err != nil {
return err
}
+ if copyUp {
+ if err := fileutils.CopyDirectory(dest, tmpDir); err != nil {
+ errMsg := fmt.Errorf("tmpcopyup: failed to copy %s to %s: %v", dest, tmpDir, err)
+ if err1 := syscall.Unmount(tmpDir, syscall.MNT_DETACH); err1 != nil {
+ return newSystemErrorWithCausef(err1, "tmpcopyup: %v: failed to unmount", errMsg)
+ }
+ return errMsg
+ }
+ if err := syscall.Mount(tmpDir, dest, "", syscall.MS_MOVE, ""); err != nil {
+ errMsg := fmt.Errorf("tmpcopyup: failed to move mount %s to %s: %v", tmpDir, dest, err)
+ if err1 := syscall.Unmount(tmpDir, syscall.MNT_DETACH); err1 != nil {
+ return newSystemErrorWithCausef(err1, "tmpcopyup: %v: failed to unmount", errMsg)
+ }
+ return errMsg
+ }
+ }
if stat != nil {
if err = os.Chmod(dest, stat.Mode()); err != nil {
return err
@@ -240,34 +290,23 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
return err
}
}
- // create symlinks for merged cgroups
- cwd, err := os.Getwd()
- if err != nil {
- return err
- }
- if err := os.Chdir(filepath.Join(rootfs, m.Destination)); err != nil {
- return err
- }
for _, mc := range merged {
for _, ss := range strings.Split(mc, ",") {
- if err := os.Symlink(mc, ss); err != nil {
- // if cgroup already exists, then okay(it could have been created before)
- if os.IsExist(err) {
- continue
- }
- os.Chdir(cwd)
+ // symlink(2) is very dumb, it will just shove the path into
+ // the link and doesn't do any checks or relative path
+ // conversion. Also, don't error out if the cgroup already exists.
+ if err := os.Symlink(mc, filepath.Join(rootfs, m.Destination, ss)); err != nil && !os.IsExist(err) {
return err
}
}
}
- if err := os.Chdir(cwd); err != nil {
- return err
- }
if m.Flags&syscall.MS_RDONLY != 0 {
// remount cgroup root as readonly
mcgrouproot := &configs.Mount{
+ Source: m.Destination,
+ Device: "bind",
Destination: m.Destination,
- Flags: defaultMountFlags | syscall.MS_RDONLY,
+ Flags: defaultMountFlags | syscall.MS_RDONLY | syscall.MS_BIND,
}
if err := remount(mcgrouproot, rootfs); err != nil {
return err
@@ -283,7 +322,7 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
}
func getCgroupMounts(m *configs.Mount) ([]*configs.Mount, error) {
- mounts, err := cgroups.GetCgroupMounts()
+ mounts, err := cgroups.GetCgroupMounts(false)
if err != nil {
return nil, err
}
@@ -307,7 +346,7 @@ func getCgroupMounts(m *configs.Mount) ([]*configs.Mount, error) {
binds = append(binds, &configs.Mount{
Device: "bind",
Source: filepath.Join(mm.Mountpoint, relDir),
- Destination: filepath.Join(m.Destination, strings.Join(mm.Subsystems, ",")),
+ Destination: filepath.Join(m.Destination, filepath.Base(mm.Mountpoint)),
Flags: syscall.MS_BIND | syscall.MS_REC | m.Flags,
PropagationFlags: m.PropagationFlags,
})
@@ -319,9 +358,6 @@ func getCgroupMounts(m *configs.Mount) ([]*configs.Mount, error) {
// checkMountDestination checks to ensure that the mount destination is not over the top of /proc.
// dest is required to be an abs path and have any symlinks resolved before calling this function.
func checkMountDestination(rootfs, dest string) error {
- if libcontainerUtils.CleanPath(rootfs) == libcontainerUtils.CleanPath(dest) {
- return fmt.Errorf("mounting into / is prohibited")
- }
invalidDestinations := []string{
"/proc",
}
@@ -333,6 +369,8 @@ func checkMountDestination(rootfs, dest string) error {
"/proc/diskstats",
"/proc/meminfo",
"/proc/stat",
+ "/proc/swaps",
+ "/proc/uptime",
"/proc/net/dev",
}
for _, valid := range validDestinations {
@@ -515,10 +553,10 @@ func getParentMount(rootfs string) (string, string, error) {
}
// Make parent mount private if it was shared
-func rootfsParentMountPrivate(config *configs.Config) error {
+func rootfsParentMountPrivate(rootfs string) error {
sharedMount := false
- parentMount, optionalOpts, err := getParentMount(config.Rootfs)
+ parentMount, optionalOpts, err := getParentMount(rootfs)
if err != nil {
return err
}
@@ -551,7 +589,10 @@ func prepareRoot(config *configs.Config) error {
return err
}
- if err := rootfsParentMountPrivate(config); err != nil {
+ // Make parent mount private to make sure following bind mount does
+ // not propagate in other namespaces. Also it will help with kernel
+ // check pass in pivot_root. (IS_SHARED(new_mnt->mnt_parent))
+ if err := rootfsParentMountPrivate(config.Rootfs); err != nil {
return err
}
@@ -562,7 +603,7 @@ func setReadonly() error {
return syscall.Mount("/", "/", "bind", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, "")
}
-func setupPtmx(config *configs.Config, console *linuxConsole) error {
+func setupPtmx(config *configs.Config) error {
ptmx := filepath.Join(config.Rootfs, "dev/ptmx")
if err := os.Remove(ptmx); err != nil && !os.IsNotExist(err) {
return err
@@ -570,47 +611,61 @@ func setupPtmx(config *configs.Config, console *linuxConsole) error {
if err := os.Symlink("pts/ptmx", ptmx); err != nil {
return fmt.Errorf("symlink dev ptmx %s", err)
}
- if console != nil {
- return console.mount(config.Rootfs, config.MountLabel)
- }
return nil
}
-func pivotRoot(rootfs, pivotBaseDir string) (err error) {
- if pivotBaseDir == "" {
- pivotBaseDir = "/"
- }
- tmpDir := filepath.Join(rootfs, pivotBaseDir)
- if err := os.MkdirAll(tmpDir, 0755); err != nil {
- return fmt.Errorf("can't create tmp dir %s, error %v", tmpDir, err)
- }
- pivotDir, err := ioutil.TempDir(tmpDir, ".pivot_root")
- if err != nil {
- return fmt.Errorf("can't create pivot_root dir %s, error %v", pivotDir, err)
- }
- defer func() {
- errVal := os.Remove(pivotDir)
- if err == nil {
- err = errVal
- }
- }()
- if err := syscall.PivotRoot(rootfs, pivotDir); err != nil {
- return fmt.Errorf("pivot_root %s", err)
- }
- if err := syscall.Chdir("/"); err != nil {
- return fmt.Errorf("chdir / %s", err)
- }
- // path to pivot dir now changed, update
- pivotDir = filepath.Join(pivotBaseDir, filepath.Base(pivotDir))
+// pivotRoot will call pivot_root such that rootfs becomes the new root
+// filesystem, and everything else is cleaned up.
+func pivotRoot(rootfs string) error {
+ // While the documentation may claim otherwise, pivot_root(".", ".") is
+ // actually valid. What this results in is / being the new root but
+ // /proc/self/cwd being the old root. Since we can play around with the cwd
+ // with pivot_root this allows us to pivot without creating directories in
+ // the rootfs. Shout-outs to the LXC developers for giving us this idea.
- // Make pivotDir rprivate to make sure any of the unmounts don't
- // propagate to parent.
- if err := syscall.Mount("", pivotDir, "", syscall.MS_PRIVATE|syscall.MS_REC, ""); err != nil {
+ oldroot, err := syscall.Open("/", syscall.O_DIRECTORY|syscall.O_RDONLY, 0)
+ if err != nil {
+ return err
+ }
+ defer syscall.Close(oldroot)
+
+ newroot, err := syscall.Open(rootfs, syscall.O_DIRECTORY|syscall.O_RDONLY, 0)
+ if err != nil {
+ return err
+ }
+ defer syscall.Close(newroot)
+
+ // Change to the new root so that the pivot_root actually acts on it.
+ if err := syscall.Fchdir(newroot); err != nil {
return err
}
- if err := syscall.Unmount(pivotDir, syscall.MNT_DETACH); err != nil {
- return fmt.Errorf("unmount pivot_root dir %s", err)
+ if err := syscall.PivotRoot(".", "."); err != nil {
+ return fmt.Errorf("pivot_root %s", err)
+ }
+
+ // Currently our "." is oldroot (according to the current kernel code).
+ // However, purely for safety, we will fchdir(oldroot) since there isn't
+ // really any guarantee from the kernel what /proc/self/cwd will be after a
+ // pivot_root(2).
+
+ if err := syscall.Fchdir(oldroot); err != nil {
+ return err
+ }
+
+ // Make oldroot rprivate to make sure our unmounts don't propagate to the
+ // host (and thus bork the machine).
+ if err := syscall.Mount("", ".", "", syscall.MS_PRIVATE|syscall.MS_REC, ""); err != nil {
+ return err
+ }
+ // Preform the unmount. MNT_DETACH allows us to unmount /proc/self/cwd.
+ if err := syscall.Unmount(".", syscall.MNT_DETACH); err != nil {
+ return err
+ }
+
+ // Switch back to our shiny new root.
+ if err := syscall.Chdir("/"); err != nil {
+ return fmt.Errorf("chdir / %s", err)
}
return nil
}
@@ -645,17 +700,26 @@ func createIfNotExists(path string, isDir bool) error {
return nil
}
-// remountReadonly will bind over the top of an existing path and ensure that it is read-only.
-func remountReadonly(path string) error {
+// readonlyPath will make a path read only.
+func readonlyPath(path string) error {
+ if err := syscall.Mount(path, path, "", syscall.MS_BIND|syscall.MS_REC, ""); err != nil {
+ if os.IsNotExist(err) {
+ return nil
+ }
+ return err
+ }
+ return syscall.Mount(path, path, "", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, "")
+}
+
+// remountReadonly will remount an existing mount point and ensure that it is read-only.
+func remountReadonly(m *configs.Mount) error {
+ var (
+ dest = m.Destination
+ flags = m.Flags
+ )
for i := 0; i < 5; i++ {
- if err := syscall.Mount("", path, "", syscall.MS_REMOUNT|syscall.MS_RDONLY, ""); err != nil && !os.IsNotExist(err) {
+ if err := syscall.Mount("", dest, "", uintptr(flags|syscall.MS_REMOUNT|syscall.MS_RDONLY), ""); err != nil {
switch err {
- case syscall.EINVAL:
- // Probably not a mountpoint, use bind-mount
- if err := syscall.Mount(path, path, "", syscall.MS_BIND, ""); err != nil {
- return err
- }
- return syscall.Mount(path, path, "", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC|defaultMountFlags, "")
case syscall.EBUSY:
time.Sleep(100 * time.Millisecond)
continue
@@ -665,13 +729,19 @@ func remountReadonly(path string) error {
}
return nil
}
- return fmt.Errorf("unable to mount %s as readonly max retries reached", path)
+ return fmt.Errorf("unable to mount %s as readonly max retries reached", dest)
}
-// maskFile bind mounts /dev/null over the top of the specified path inside a container
-// to avoid security issues from processes reading information from non-namespace aware mounts ( proc/kcore ).
-func maskFile(path string) error {
+// maskPath masks the top of the specified path inside a container to avoid
+// security issues from processes reading information from non-namespace aware
+// mounts ( proc/kcore ).
+// For files, maskPath bind mounts /dev/null over the top of the specified path.
+// For directories, maskPath mounts read-only tmpfs over the top of the specified path.
+func maskPath(path string) error {
if err := syscall.Mount("/dev/null", path, "", syscall.MS_BIND, ""); err != nil && !os.IsNotExist(err) {
+ if err == syscall.ENOTDIR {
+ return syscall.Mount("tmpfs", path, "tmpfs", syscall.MS_RDONLY, "")
+ }
return err
}
return nil
@@ -705,10 +775,12 @@ func mountPropagate(m *configs.Mount, rootfs string, mountLabel string) error {
data = label.FormatMountLabel(m.Data, mountLabel)
flags = m.Flags
)
- if dest == "/dev" {
+ if libcontainerUtils.CleanPath(dest) == "/dev" {
flags &= ^syscall.MS_RDONLY
}
- if !strings.HasPrefix(dest, rootfs) {
+
+ copyUp := m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP
+ if !(copyUp || strings.HasPrefix(dest, rootfs)) {
dest = filepath.Join(rootfs, dest)
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux_test.go b/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux_test.go
index f70e10be..f2453e2b 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux_test.go
@@ -32,14 +32,6 @@ func TestCheckMountDestFalsePositive(t *testing.T) {
}
}
-func TestCheckMountRoot(t *testing.T) {
- dest := "/rootfs"
- err := checkMountDestination("/rootfs", dest)
- if err == nil {
- t.Fatal(err)
- }
-}
-
func TestNeedsSetupDev(t *testing.T) {
config := &configs.Config{
Mounts: []*configs.Mount{
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go
index 3b9a7595..ded5a6bb 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go
@@ -36,6 +36,11 @@ var archs = map[string]string{
"SCMP_ARCH_MIPSEL": "mipsel",
"SCMP_ARCH_MIPSEL64": "mipsel64",
"SCMP_ARCH_MIPSEL64N32": "mipsel64n32",
+ "SCMP_ARCH_PPC": "ppc",
+ "SCMP_ARCH_PPC64": "ppc64",
+ "SCMP_ARCH_PPC64LE": "ppc64le",
+ "SCMP_ARCH_S390": "s390",
+ "SCMP_ARCH_S390X": "s390x",
}
// ConvertStringToOperator converts a string into a Seccomp comparison operator.
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go
index ec0ac1c0..518d2c38 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go
@@ -212,10 +212,6 @@ func parseStatusFile(path string) (map[string]string, error) {
status := make(map[string]string)
for s.Scan() {
- if err := s.Err(); err != nil {
- return nil, err
- }
-
text := s.Text()
parts := strings.Split(text, ":")
@@ -225,5 +221,9 @@ func parseStatusFile(path string) (map[string]string, error) {
status[parts[0]] = parts[1]
}
+ if err := s.Err(); err != nil {
+ return nil, err
+ }
+
return status, nil
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_unsupported.go
index 888483e7..44df1ad4 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_unsupported.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_unsupported.go
@@ -10,7 +10,7 @@ import (
var ErrSeccompNotEnabled = errors.New("seccomp: config provided but seccomp not supported")
-// Seccomp not supported, do nothing
+// InitSeccomp does nothing because seccomp is not supported.
func InitSeccomp(config *configs.Seccomp) error {
if config != nil {
return ErrSeccompNotEnabled
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/selinux/selinux.go b/vendor/github.com/opencontainers/runc/libcontainer/selinux/selinux.go
index 255080c6..5bd028bf 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/selinux/selinux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/selinux/selinux.go
@@ -16,7 +16,6 @@ import (
"sync"
"syscall"
- "github.com/docker/docker/pkg/mount"
"github.com/opencontainers/runc/libcontainer/system"
)
@@ -33,20 +32,106 @@ const (
stRdOnly = 0x01
)
+type selinuxState struct {
+ enabledSet bool
+ enabled bool
+ selinuxfsSet bool
+ selinuxfs string
+ mcsList map[string]bool
+ sync.Mutex
+}
+
var (
- assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
- mcsList = make(map[string]bool)
- mcsLock sync.Mutex
- selinuxfs = "unknown"
- selinuxEnabled = false // Stores whether selinux is currently enabled
- selinuxEnabledChecked = false // Stores whether selinux enablement has been checked or established yet
+ assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
+ state = selinuxState{
+ mcsList: make(map[string]bool),
+ }
)
type SELinuxContext map[string]string
+func (s *selinuxState) setEnable(enabled bool) bool {
+ s.Lock()
+ defer s.Unlock()
+ s.enabledSet = true
+ s.enabled = enabled
+ return s.enabled
+}
+
+func (s *selinuxState) getEnabled() bool {
+ s.Lock()
+ enabled := s.enabled
+ enabledSet := s.enabledSet
+ s.Unlock()
+ if enabledSet {
+ return enabled
+ }
+
+ enabled = false
+ if fs := getSelinuxMountPoint(); fs != "" {
+ if con, _ := Getcon(); con != "kernel" {
+ enabled = true
+ }
+ }
+ return s.setEnable(enabled)
+}
+
// SetDisabled disables selinux support for the package
func SetDisabled() {
- selinuxEnabled, selinuxEnabledChecked = false, true
+ state.setEnable(false)
+}
+
+func (s *selinuxState) setSELinuxfs(selinuxfs string) string {
+ s.Lock()
+ defer s.Unlock()
+ s.selinuxfsSet = true
+ s.selinuxfs = selinuxfs
+ return s.selinuxfs
+}
+
+func (s *selinuxState) getSELinuxfs() string {
+ s.Lock()
+ selinuxfs := s.selinuxfs
+ selinuxfsSet := s.selinuxfsSet
+ s.Unlock()
+ if selinuxfsSet {
+ return selinuxfs
+ }
+
+ selinuxfs = ""
+ f, err := os.Open("/proc/self/mountinfo")
+ if err != nil {
+ return selinuxfs
+ }
+ defer f.Close()
+
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ txt := scanner.Text()
+ // Safe as mountinfo encodes mountpoints with spaces as \040.
+ sepIdx := strings.Index(txt, " - ")
+ if sepIdx == -1 {
+ continue
+ }
+ if !strings.Contains(txt[sepIdx:], "selinuxfs") {
+ continue
+ }
+ fields := strings.Split(txt, " ")
+ if len(fields) < 5 {
+ continue
+ }
+ selinuxfs = fields[4]
+ break
+ }
+
+ if selinuxfs != "" {
+ var buf syscall.Statfs_t
+ syscall.Statfs(selinuxfs, &buf)
+ if (buf.Flags & stRdOnly) == 1 {
+ selinuxfs = ""
+ }
+ }
+ return s.setSELinuxfs(selinuxfs)
}
// getSelinuxMountPoint returns the path to the mountpoint of an selinuxfs
@@ -55,43 +140,12 @@ func SetDisabled() {
// processes. The existence of an selinuxfs mount is used to determine
// whether selinux is currently enabled or not.
func getSelinuxMountPoint() string {
- if selinuxfs != "unknown" {
- return selinuxfs
- }
- selinuxfs = ""
-
- mounts, err := mount.GetMounts()
- if err != nil {
- return selinuxfs
- }
- for _, mount := range mounts {
- if mount.Fstype == "selinuxfs" {
- selinuxfs = mount.Mountpoint
- break
- }
- }
- if selinuxfs != "" {
- var buf syscall.Statfs_t
- syscall.Statfs(selinuxfs, &buf)
- if (buf.Flags & stRdOnly) == 1 {
- selinuxfs = ""
- }
- }
- return selinuxfs
+ return state.getSELinuxfs()
}
// SelinuxEnabled returns whether selinux is currently enabled.
func SelinuxEnabled() bool {
- if selinuxEnabledChecked {
- return selinuxEnabled
- }
- selinuxEnabledChecked = true
- if fs := getSelinuxMountPoint(); fs != "" {
- if con, _ := Getcon(); con != "kernel" {
- selinuxEnabled = true
- }
- }
- return selinuxEnabled
+ return state.getEnabled()
}
func readConfig(target string) (value string) {
@@ -269,19 +323,19 @@ func SelinuxGetEnforceMode() int {
}
func mcsAdd(mcs string) error {
- mcsLock.Lock()
- defer mcsLock.Unlock()
- if mcsList[mcs] {
+ state.Lock()
+ defer state.Unlock()
+ if state.mcsList[mcs] {
return fmt.Errorf("MCS Label already exists")
}
- mcsList[mcs] = true
+ state.mcsList[mcs] = true
return nil
}
func mcsDelete(mcs string) {
- mcsLock.Lock()
- mcsList[mcs] = false
- mcsLock.Unlock()
+ state.Lock()
+ defer state.Unlock()
+ state.mcsList[mcs] = false
}
func IntToMcs(id int, catRange uint32) string {
@@ -297,7 +351,7 @@ func IntToMcs(id int, catRange uint32) string {
for ORD > TIER {
ORD = ORD - TIER
- TIER -= 1
+ TIER--
}
TIER = SETSIZE - TIER
ORD = ORD + TIER
@@ -320,9 +374,7 @@ func uniqMcs(catRange uint32) string {
continue
} else {
if c1 > c2 {
- t := c1
- c1 = c2
- c2 = t
+ c1, c2 = c2, c1
}
}
mcs = fmt.Sprintf("s0:c%d,c%d", c1, c2)
@@ -341,6 +393,12 @@ func FreeLxcContexts(scon string) {
}
}
+var roFileLabel string
+
+func GetROFileLabel() (fileLabel string) {
+ return roFileLabel
+}
+
func GetLxcContexts() (processLabel string, fileLabel string) {
var (
val, key string
@@ -385,6 +443,9 @@ func GetLxcContexts() (processLabel string, fileLabel string) {
if key == "file" {
fileLabel = strings.Trim(val, "\"")
}
+ if key == "ro_file" {
+ roFileLabel = strings.Trim(val, "\"")
+ }
}
}
@@ -392,6 +453,9 @@ func GetLxcContexts() (processLabel string, fileLabel string) {
return "", ""
}
+ if roFileLabel == "" {
+ roFileLabel = fileLabel
+ }
exit:
// mcs := IntToMcs(os.Getpid(), 1024)
mcs := uniqMcs(1024)
@@ -432,13 +496,13 @@ func badPrefix(fpath string) error {
for _, prefix := range badprefixes {
if fpath == prefix || strings.HasPrefix(fpath, fmt.Sprintf("%s/", prefix)) {
- return fmt.Errorf("Relabeling content in %s is not allowed.", prefix)
+ return fmt.Errorf("relabeling content in %s is not allowed", prefix)
}
}
return nil
}
-// Change the fpath file object to the SELinux label scon.
+// Chcon changes the fpath file object to the SELinux label scon.
// If the fpath is a directory and recurse is true Chcon will walk the
// directory tree setting the label
func Chcon(fpath string, scon string, recurse bool) error {
@@ -472,14 +536,14 @@ func DupSecOpt(src string) []string {
con["level"] == "" {
return nil
}
- return []string{"label:user:" + con["user"],
- "label:role:" + con["role"],
- "label:type:" + con["type"],
- "label:level:" + con["level"]}
+ return []string{"user:" + con["user"],
+ "role:" + con["role"],
+ "type:" + con["type"],
+ "level:" + con["level"]}
}
// DisableSecOpt returns a security opt that can be used to disabling SELinux
// labeling support for future container processes
func DisableSecOpt() []string {
- return []string{"label:disable"}
+ return []string{"disable"}
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go
index b1a198fd..2e80450d 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go
@@ -16,6 +16,7 @@ import (
// linuxSetnsInit performs the container's initialization for running a new process
// inside an existing container.
type linuxSetnsInit struct {
+ pipe *os.File
config *initConfig
}
@@ -24,9 +25,19 @@ func (l *linuxSetnsInit) getSessionRingName() string {
}
func (l *linuxSetnsInit) Init() error {
- // do not inherit the parent's session keyring
- if _, err := keyctl.JoinSessionKeyring(l.getSessionRingName()); err != nil {
- return err
+ if !l.config.Config.NoNewKeyring {
+ // do not inherit the parent's session keyring
+ if _, err := keys.JoinSessionKeyring(l.getSessionRingName()); err != nil {
+ return err
+ }
+ }
+ if l.config.CreateConsole {
+ if err := setupConsole(l.pipe, l.config, false); err != nil {
+ return err
+ }
+ if err := system.Setctty(); err != nil {
+ return err
+ }
}
if l.config.NoNewPrivileges {
if err := system.Prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil {
@@ -44,10 +55,8 @@ func (l *linuxSetnsInit) Init() error {
if err := apparmor.ApplyProfile(l.config.AppArmorProfile); err != nil {
return err
}
- if l.config.ProcessLabel != "" {
- if err := label.SetProcessLabel(l.config.ProcessLabel); err != nil {
- return err
- }
+ if err := label.SetProcessLabel(l.config.ProcessLabel); err != nil {
+ return err
}
return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/specconv/spec_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/specconv/spec_linux.go
index f27b7e0d..94afd65c 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/specconv/spec_linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/specconv/spec_linux.go
@@ -8,12 +8,10 @@ import (
"fmt"
"os"
"path/filepath"
- "strconv"
"strings"
"syscall"
"time"
- "github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/seccomp"
libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils"
@@ -22,7 +20,7 @@ import (
const wildcard = -1
-var namespaceMapping = map[specs.NamespaceType]configs.NamespaceType{
+var namespaceMapping = map[specs.LinuxNamespaceType]configs.NamespaceType{
specs.PIDNamespace: configs.NEWPID,
specs.NetworkNamespace: configs.NEWNET,
specs.MountNamespace: configs.NEWNS,
@@ -145,6 +143,7 @@ type CreateOpts struct {
CgroupName string
UseSystemdCgroup bool
NoPivotRoot bool
+ NoNewKeyring bool
Spec *specs.Spec
}
@@ -165,14 +164,17 @@ func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) {
if !filepath.IsAbs(rootfsPath) {
rootfsPath = filepath.Join(cwd, rootfsPath)
}
+ labels := []string{}
+ for k, v := range spec.Annotations {
+ labels = append(labels, fmt.Sprintf("%s=%s", k, v))
+ }
config := &configs.Config{
- Rootfs: rootfsPath,
- NoPivotRoot: opts.NoPivotRoot,
- Readonlyfs: spec.Root.Readonly,
- Hostname: spec.Hostname,
- Labels: []string{
- "bundle=" + cwd,
- },
+ Rootfs: rootfsPath,
+ NoPivotRoot: opts.NoPivotRoot,
+ Readonlyfs: spec.Root.Readonly,
+ Hostname: spec.Hostname,
+ Labels: append(labels, fmt.Sprintf("bundle=%s", cwd)),
+ NoNewKeyring: opts.NoNewKeyring,
}
exists := false
@@ -185,6 +187,9 @@ func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) {
if !exists {
return nil, fmt.Errorf("namespace %q does not exist", ns)
}
+ if config.Namespaces.Contains(t) {
+ return nil, fmt.Errorf("malformed spec file: duplicated ns %q", ns)
+ }
config.Namespaces.Add(t, ns.Path)
}
if config.Namespaces.Contains(configs.NEWNET) {
@@ -218,12 +223,12 @@ func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) {
}
config.Seccomp = seccomp
}
- config.Sysctl = spec.Linux.Sysctl
- if oomScoreAdj := spec.Linux.Resources.OOMScoreAdj; oomScoreAdj != nil {
- config.OomScoreAdj = *oomScoreAdj
+ if spec.Process.SelinuxLabel != "" {
+ config.ProcessLabel = spec.Process.SelinuxLabel
}
- for _, g := range spec.Process.User.AdditionalGids {
- config.AdditionalGroups = append(config.AdditionalGroups, strconv.FormatUint(uint64(g), 10))
+ config.Sysctl = spec.Linux.Sysctl
+ if spec.Linux.Resources != nil && spec.Linux.Resources.OOMScoreAdj != nil {
+ config.OomScoreAdj = *spec.Linux.Resources.OOMScoreAdj
}
createHooks(spec, config)
config.MountLabel = spec.Linux.MountLabel
@@ -232,7 +237,7 @@ func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) {
}
func createLibcontainerMount(cwd string, m specs.Mount) *configs.Mount {
- flags, pgflags, data := parseMountOptions(m.Options)
+ flags, pgflags, data, ext := parseMountOptions(m.Options)
source := m.Source
if m.Type == "bind" {
if !filepath.IsAbs(source) {
@@ -246,20 +251,18 @@ func createLibcontainerMount(cwd string, m specs.Mount) *configs.Mount {
Data: data,
Flags: flags,
PropagationFlags: pgflags,
+ Extensions: ext,
}
}
func createCgroupConfig(name string, useSystemdCgroup bool, spec *specs.Spec) (*configs.Cgroup, error) {
- var (
- err error
- myCgroupPath string
- )
+ var myCgroupPath string
c := &configs.Cgroup{
Resources: &configs.Resources{},
}
- if spec.Linux.CgroupsPath != nil {
+ if spec.Linux != nil && spec.Linux.CgroupsPath != nil {
myCgroupPath = libcontainerUtils.CleanPath(*spec.Linux.CgroupsPath)
if useSystemdCgroup {
myCgroupPath = *spec.Linux.CgroupsPath
@@ -284,16 +287,15 @@ func createCgroupConfig(name string, useSystemdCgroup bool, spec *specs.Spec) (*
}
} else {
if myCgroupPath == "" {
- myCgroupPath, err = cgroups.GetThisCgroupDir("devices")
- if err != nil {
- return nil, err
- }
- myCgroupPath = filepath.Join(myCgroupPath, name)
+ c.Name = name
}
c.Path = myCgroupPath
}
c.Resources.AllowedDevices = allowedDevices
+ if spec.Linux == nil {
+ return c, nil
+ }
r := spec.Linux.Resources
if r == nil {
return c, nil
@@ -376,7 +378,7 @@ func createCgroupConfig(name string, useSystemdCgroup bool, spec *specs.Spec) (*
}
}
if r.Pids != nil {
- c.Resources.PidsLimit = *r.Pids.Limit
+ c.Resources.PidsLimit = r.Pids.Limit
}
if r.BlockIO != nil {
if r.BlockIO.Weight != nil {
@@ -387,39 +389,50 @@ func createCgroupConfig(name string, useSystemdCgroup bool, spec *specs.Spec) (*
}
if r.BlockIO.WeightDevice != nil {
for _, wd := range r.BlockIO.WeightDevice {
- weightDevice := configs.NewWeightDevice(wd.Major, wd.Minor, *wd.Weight, *wd.LeafWeight)
+ var weight, leafWeight uint16
+ if wd.Weight != nil {
+ weight = *wd.Weight
+ }
+ if wd.LeafWeight != nil {
+ leafWeight = *wd.LeafWeight
+ }
+ weightDevice := configs.NewWeightDevice(wd.Major, wd.Minor, weight, leafWeight)
c.Resources.BlkioWeightDevice = append(c.Resources.BlkioWeightDevice, weightDevice)
}
}
if r.BlockIO.ThrottleReadBpsDevice != nil {
for _, td := range r.BlockIO.ThrottleReadBpsDevice {
- throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
+ rate := td.Rate
+ throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, rate)
c.Resources.BlkioThrottleReadBpsDevice = append(c.Resources.BlkioThrottleReadBpsDevice, throttleDevice)
}
}
if r.BlockIO.ThrottleWriteBpsDevice != nil {
for _, td := range r.BlockIO.ThrottleWriteBpsDevice {
- throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
+ rate := td.Rate
+ throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, rate)
c.Resources.BlkioThrottleWriteBpsDevice = append(c.Resources.BlkioThrottleWriteBpsDevice, throttleDevice)
}
}
if r.BlockIO.ThrottleReadIOPSDevice != nil {
for _, td := range r.BlockIO.ThrottleReadIOPSDevice {
- throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
+ rate := td.Rate
+ throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, rate)
c.Resources.BlkioThrottleReadIOPSDevice = append(c.Resources.BlkioThrottleReadIOPSDevice, throttleDevice)
}
}
if r.BlockIO.ThrottleWriteIOPSDevice != nil {
for _, td := range r.BlockIO.ThrottleWriteIOPSDevice {
- throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
+ rate := td.Rate
+ throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, rate)
c.Resources.BlkioThrottleWriteIOPSDevice = append(c.Resources.BlkioThrottleWriteIOPSDevice, throttleDevice)
}
}
}
for _, l := range r.HugepageLimits {
c.Resources.HugetlbLimit = append(c.Resources.HugetlbLimit, &configs.HugepageLimit{
- Pagesize: *l.Pagesize,
- Limit: *l.Limit,
+ Pagesize: l.Pagesize,
+ Limit: l.Limit,
})
}
if r.DisableOOMKiller != nil {
@@ -427,7 +440,7 @@ func createCgroupConfig(name string, useSystemdCgroup bool, spec *specs.Spec) (*
}
if r.Network != nil {
if r.Network.ClassID != nil {
- c.Resources.NetClsClassid = string(*r.Network.ClassID)
+ c.Resources.NetClsClassid = *r.Network.ClassID
}
for _, m := range r.Network.Priorities {
c.Resources.NetPrioIfpriomap = append(c.Resources.NetPrioIfpriomap, &configs.IfPrioMap{
@@ -513,6 +526,8 @@ func createDevices(spec *specs.Spec, config *configs.Config) error {
// merge in additional devices from the spec
for _, d := range spec.Linux.Devices {
var uid, gid uint32
+ var filemode os.FileMode = 0666
+
if d.UID != nil {
uid = *d.UID
}
@@ -523,12 +538,15 @@ func createDevices(spec *specs.Spec, config *configs.Config) error {
if err != nil {
return err
}
+ if d.FileMode != nil {
+ filemode = *d.FileMode
+ }
device := &configs.Device{
Type: dt,
Path: d.Path,
Major: d.Major,
Minor: d.Minor,
- FileMode: *d.FileMode,
+ FileMode: filemode,
Uid: uid,
Gid: gid,
}
@@ -541,11 +559,7 @@ func setupUserNamespace(spec *specs.Spec, config *configs.Config) error {
if len(spec.Linux.UIDMappings) == 0 {
return nil
}
- // do not override the specified user namespace path
- if config.Namespaces.PathOf(configs.NEWUSER) == "" {
- config.Namespaces.Add(configs.NEWUSER, "")
- }
- create := func(m specs.IDMapping) configs.IDMap {
+ create := func(m specs.LinuxIDMapping) configs.IDMap {
return configs.IDMap{
HostID: int(m.HostID),
ContainerID: int(m.ContainerID),
@@ -575,11 +589,12 @@ func setupUserNamespace(spec *specs.Spec, config *configs.Config) error {
// parseMountOptions parses the string and returns the flags, propagation
// flags and any mount data that it contains.
-func parseMountOptions(options []string) (int, []int, string) {
+func parseMountOptions(options []string) (int, []int, string, int) {
var (
- flag int
- pgflag []int
- data []string
+ flag int
+ pgflag []int
+ data []string
+ extFlags int
)
flags := map[string]struct {
clear bool
@@ -611,18 +626,21 @@ func parseMountOptions(options []string) (int, []int, string) {
"suid": {true, syscall.MS_NOSUID},
"sync": {false, syscall.MS_SYNCHRONOUS},
}
- propagationFlags := map[string]struct {
+ propagationFlags := map[string]int{
+ "private": syscall.MS_PRIVATE,
+ "shared": syscall.MS_SHARED,
+ "slave": syscall.MS_SLAVE,
+ "unbindable": syscall.MS_UNBINDABLE,
+ "rprivate": syscall.MS_PRIVATE | syscall.MS_REC,
+ "rshared": syscall.MS_SHARED | syscall.MS_REC,
+ "rslave": syscall.MS_SLAVE | syscall.MS_REC,
+ "runbindable": syscall.MS_UNBINDABLE | syscall.MS_REC,
+ }
+ extensionFlags := map[string]struct {
clear bool
flag int
}{
- "private": {false, syscall.MS_PRIVATE},
- "shared": {false, syscall.MS_SHARED},
- "slave": {false, syscall.MS_SLAVE},
- "unbindable": {false, syscall.MS_UNBINDABLE},
- "rprivate": {false, syscall.MS_PRIVATE | syscall.MS_REC},
- "rshared": {false, syscall.MS_SHARED | syscall.MS_REC},
- "rslave": {false, syscall.MS_SLAVE | syscall.MS_REC},
- "runbindable": {false, syscall.MS_UNBINDABLE | syscall.MS_REC},
+ "tmpcopyup": {false, configs.EXT_COPYUP},
}
for _, o := range options {
// If the option does not exist in the flags table or the flag
@@ -634,16 +652,22 @@ func parseMountOptions(options []string) (int, []int, string) {
} else {
flag |= f.flag
}
- } else if f, exists := propagationFlags[o]; exists && f.flag != 0 {
- pgflag = append(pgflag, f.flag)
+ } else if f, exists := propagationFlags[o]; exists && f != 0 {
+ pgflag = append(pgflag, f)
+ } else if f, exists := extensionFlags[o]; exists && f.flag != 0 {
+ if f.clear {
+ extFlags &= ^f.flag
+ } else {
+ extFlags |= f.flag
+ }
} else {
data = append(data, o)
}
}
- return flag, pgflag, strings.Join(data, ",")
+ return flag, pgflag, strings.Join(data, ","), extFlags
}
-func setupSeccomp(config *specs.Seccomp) (*configs.Seccomp, error) {
+func setupSeccomp(config *specs.LinuxSeccomp) (*configs.Seccomp, error) {
if config == nil {
return nil, nil
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/specconv/spec_linux_test.go b/vendor/github.com/opencontainers/runc/libcontainer/specconv/spec_linux_test.go
index da842057..d3c8fae7 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/specconv/spec_linux_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/specconv/spec_linux_test.go
@@ -1,9 +1,8 @@
-// build +linux
+// +build linux
package specconv
import (
- "strings"
"testing"
"github.com/opencontainers/runtime-spec/specs-go"
@@ -13,7 +12,9 @@ func TestLinuxCgroupsPathSpecified(t *testing.T) {
cgroupsPath := "/user/cgroups/path/id"
spec := &specs.Spec{}
- spec.Linux.CgroupsPath = &cgroupsPath
+ spec.Linux = &specs.Linux{
+ CgroupsPath: &cgroupsPath,
+ }
cgroup, err := createCgroupConfig("ContainerID", false, spec)
if err != nil {
@@ -33,7 +34,31 @@ func TestLinuxCgroupsPathNotSpecified(t *testing.T) {
t.Errorf("Couldn't create Cgroup config: %v", err)
}
- if !strings.HasSuffix(cgroup.Path, "/ContainerID") {
- t.Errorf("Wrong cgroupsPath, expected it to have suffix '%s' got '%s'", "/ContainerID", cgroup.Path)
+ if cgroup.Path != "" {
+ t.Errorf("Wrong cgroupsPath, expected it to be empty string, got '%s'", cgroup.Path)
+ }
+}
+
+func TestDupNamespaces(t *testing.T) {
+ spec := &specs.Spec{
+ Linux: &specs.Linux{
+ Namespaces: []specs.LinuxNamespace{
+ {
+ Type: "pid",
+ },
+ {
+ Type: "pid",
+ Path: "/proc/1/ns/pid",
+ },
+ },
+ },
+ }
+
+ _, err := CreateLibcontainerConfig(&CreateOpts{
+ Spec: spec,
+ })
+
+ if err == nil {
+ t.Errorf("Duplicated namespaces should be forbidden")
}
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/stacktrace/capture.go b/vendor/github.com/opencontainers/runc/libcontainer/stacktrace/capture.go
index 5ee6e37a..0bbe1495 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/stacktrace/capture.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/stacktrace/capture.go
@@ -2,14 +2,14 @@ package stacktrace
import "runtime"
-// Caputure captures a stacktrace for the current calling go program
+// Capture captures a stacktrace for the current calling go program
//
// skip is the number of frames to skip
func Capture(userSkip int) Stacktrace {
var (
skip = userSkip + 1 // add one for our own function
frames []Frame
- prevPc uintptr = 0
+ prevPc uintptr
)
for i := skip; ; i++ {
pc, file, line, ok := runtime.Caller(i)
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/stacktrace/capture_test.go b/vendor/github.com/opencontainers/runc/libcontainer/stacktrace/capture_test.go
index 7e99a266..18ca924e 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/stacktrace/capture_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/stacktrace/capture_test.go
@@ -19,9 +19,9 @@ func TestCaptureTestFunc(t *testing.T) {
// the first frame is the caller
frame := stack.Frames[0]
if expected := "captureFunc"; frame.Function != expected {
- t.Fatalf("expteced function %q but recevied %q", expected, frame.Function)
+ t.Fatalf("expected function %q but recevied %q", expected, frame.Function)
}
- expected := "github.com/opencontainers/runc/libcontainer/stacktrace"
+ expected := "/runc/libcontainer/stacktrace"
if !strings.HasSuffix(frame.Package, expected) {
t.Fatalf("expected package %q but received %q", expected, frame.Package)
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go
index 59bd3700..7b68458e 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go
@@ -4,8 +4,8 @@ package libcontainer
import (
"fmt"
- "io"
"os"
+ "os/exec"
"syscall"
"github.com/opencontainers/runc/libcontainer/apparmor"
@@ -17,9 +17,10 @@ import (
)
type linuxStandardInit struct {
- pipe io.ReadWriter
- parentPid int
- config *initConfig
+ pipe *os.File
+ parentPid int
+ stateDirFD int
+ config *initConfig
}
func (l *linuxStandardInit) getSessionRingParams() (string, uint32, uint32) {
@@ -43,30 +44,20 @@ func (l *linuxStandardInit) getSessionRingParams() (string, uint32, uint32) {
const PR_SET_NO_NEW_PRIVS = 0x26
func (l *linuxStandardInit) Init() error {
- ringname, keepperms, newperms := l.getSessionRingParams()
+ if !l.config.Config.NoNewKeyring {
+ ringname, keepperms, newperms := l.getSessionRingParams()
- // do not inherit the parent's session keyring
- sessKeyId, err := keyctl.JoinSessionKeyring(ringname)
- if err != nil {
- return err
- }
- // make session keyring searcheable
- if err := keyctl.ModKeyringPerm(sessKeyId, keepperms, newperms); err != nil {
- return err
- }
-
- var console *linuxConsole
- if l.config.Console != "" {
- console = newConsoleFromPath(l.config.Console)
- if err := console.dupStdio(); err != nil {
- return err
- }
- }
- if console != nil {
- if err := system.Setctty(); err != nil {
+ // do not inherit the parent's session keyring
+ sessKeyId, err := keys.JoinSessionKeyring(ringname)
+ if err != nil {
+ return err
+ }
+ // make session keyring searcheable
+ if err := keys.ModKeyringPerm(sessKeyId, keepperms, newperms); err != nil {
return err
}
}
+
if err := setupNetwork(l.config); err != nil {
return err
}
@@ -75,12 +66,33 @@ func (l *linuxStandardInit) Init() error {
}
label.Init()
- // InitializeMountNamespace() can be executed only for a new mount namespace
+
+ // prepareRootfs() can be executed only for a new mount namespace.
if l.config.Config.Namespaces.Contains(configs.NEWNS) {
- if err := setupRootfs(l.config.Config, console, l.pipe); err != nil {
+ if err := prepareRootfs(l.pipe, l.config.Config); err != nil {
return err
}
}
+
+ // Set up the console. This has to be done *before* we finalize the rootfs,
+ // but *after* we've given the user the chance to set up all of the mounts
+ // they wanted.
+ if l.config.CreateConsole {
+ if err := setupConsole(l.pipe, l.config, true); err != nil {
+ return err
+ }
+ if err := system.Setctty(); err != nil {
+ return err
+ }
+ }
+
+ // Finish the rootfs setup.
+ if l.config.Config.Namespaces.Contains(configs.NEWNS) {
+ if err := finalizeRootfs(l.config.Config); err != nil {
+ return err
+ }
+ }
+
if hostname := l.config.Config.Hostname; hostname != "" {
if err := syscall.Sethostname([]byte(hostname)); err != nil {
return err
@@ -99,12 +111,12 @@ func (l *linuxStandardInit) Init() error {
}
}
for _, path := range l.config.Config.ReadonlyPaths {
- if err := remountReadonly(path); err != nil {
+ if err := readonlyPath(path); err != nil {
return err
}
}
for _, path := range l.config.Config.MaskPaths {
- if err := maskFile(path); err != nil {
+ if err := maskPath(path); err != nil {
return err
}
}
@@ -123,7 +135,10 @@ func (l *linuxStandardInit) Init() error {
if err := syncParentReady(l.pipe); err != nil {
return err
}
- if l.config.Config.Seccomp != nil {
+ // Without NoNewPrivileges seccomp is a privileged operation, so we need to
+ // do this before dropping capabilities; otherwise do it as late as possible
+ // just before execve so as few syscalls take place after it as possible.
+ if l.config.Config.Seccomp != nil && !l.config.NoNewPrivileges {
if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil {
return err
}
@@ -136,12 +151,39 @@ func (l *linuxStandardInit) Init() error {
if err := pdeath.Restore(); err != nil {
return err
}
- // compare the parent from the inital start of the init process and make sure that it did not change.
- // if the parent changes that means it died and we were reparened to something else so we should
+ // compare the parent from the initial start of the init process and make sure that it did not change.
+ // if the parent changes that means it died and we were reparented to something else so we should
// just kill ourself and not cause problems for someone else.
if syscall.Getppid() != l.parentPid {
return syscall.Kill(syscall.Getpid(), syscall.SIGKILL)
}
-
- return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())
+ // check for the arg before waiting to make sure it exists and it is returned
+ // as a create time error.
+ name, err := exec.LookPath(l.config.Args[0])
+ if err != nil {
+ return err
+ }
+ // close the pipe to signal that we have completed our init.
+ l.pipe.Close()
+ // wait for the fifo to be opened on the other side before
+ // exec'ing the users process.
+ fd, err := syscall.Openat(l.stateDirFD, execFifoFilename, os.O_WRONLY|syscall.O_CLOEXEC, 0)
+ if err != nil {
+ return newSystemErrorWithCause(err, "openat exec fifo")
+ }
+ if _, err := syscall.Write(fd, []byte("0")); err != nil {
+ return newSystemErrorWithCause(err, "write 0 exec fifo")
+ }
+ if l.config.Config.Seccomp != nil && l.config.NoNewPrivileges {
+ if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil {
+ return newSystemErrorWithCause(err, "init seccomp")
+ }
+ }
+ // close the statedir fd before exec because the kernel resets dumpable in the wrong order
+ // https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318
+ syscall.Close(l.stateDirFD)
+ if err := syscall.Exec(name, l.config.Args[0:], os.Environ()); err != nil {
+ return newSystemErrorWithCause(err, "exec user process")
+ }
+ return nil
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/state_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/state_linux.go
index d2618f69..c7d3727e 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/state_linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/state_linux.go
@@ -6,6 +6,7 @@ import (
"fmt"
"os"
"path/filepath"
+ "syscall"
"github.com/Sirupsen/logrus"
"github.com/opencontainers/runc/libcontainer/configs"
@@ -38,7 +39,7 @@ type containerState interface {
func destroy(c *linuxContainer) error {
if !c.config.Namespaces.Contains(configs.NEWPID) {
- if err := killCgroupProcesses(c.cgroupManager); err != nil {
+ if err := signalAllProcesses(c.cgroupManager, syscall.SIGKILL); err != nil {
logrus.Warn(err)
}
}
@@ -59,7 +60,6 @@ func runPoststopHooks(c *linuxContainer) error {
s := configs.HookState{
Version: c.config.Version,
ID: c.id,
- Root: c.config.Rootfs,
BundlePath: utils.SearchLabels(c.config.Labels, "bundle"),
}
for _, hook := range c.config.Hooks.Poststop {
@@ -77,15 +77,12 @@ type stoppedState struct {
}
func (b *stoppedState) status() Status {
- return Destroyed
+ return Stopped
}
func (b *stoppedState) transition(s containerState) error {
switch s.(type) {
- case *runningState:
- b.c.state = s
- return nil
- case *restoredState:
+ case *runningState, *restoredState:
b.c.state = s
return nil
case *stoppedState:
@@ -110,11 +107,11 @@ func (r *runningState) status() Status {
func (r *runningState) transition(s containerState) error {
switch s.(type) {
case *stoppedState:
- running, err := r.c.isRunning()
+ t, err := r.c.runType()
if err != nil {
return err
}
- if running {
+ if t == Running {
return newGenericError(fmt.Errorf("container still running"), ContainerNotStopped)
}
r.c.state = s
@@ -129,16 +126,40 @@ func (r *runningState) transition(s containerState) error {
}
func (r *runningState) destroy() error {
- running, err := r.c.isRunning()
+ t, err := r.c.runType()
if err != nil {
return err
}
- if running {
+ if t == Running {
return newGenericError(fmt.Errorf("container is not destroyed"), ContainerNotStopped)
}
return destroy(r.c)
}
+type createdState struct {
+ c *linuxContainer
+}
+
+func (i *createdState) status() Status {
+ return Created
+}
+
+func (i *createdState) transition(s containerState) error {
+ switch s.(type) {
+ case *runningState, *pausedState, *stoppedState:
+ i.c.state = s
+ return nil
+ case *createdState:
+ return nil
+ }
+ return newStateTransitionError(i, s)
+}
+
+func (i *createdState) destroy() error {
+ i.c.initProcess.signal(syscall.SIGKILL)
+ return destroy(i.c)
+}
+
// pausedState represents a container that is currently pause. It cannot be destroyed in a
// paused state and must transition back to running first.
type pausedState struct {
@@ -161,11 +182,11 @@ func (p *pausedState) transition(s containerState) error {
}
func (p *pausedState) destroy() error {
- isRunning, err := p.c.isRunning()
+ t, err := p.c.runType()
if err != nil {
return err
}
- if !isRunning {
+ if t != Running && t != Created {
if err := p.c.cgroupManager.Freeze(configs.Thawed); err != nil {
return err
}
@@ -174,8 +195,8 @@ func (p *pausedState) destroy() error {
return newGenericError(fmt.Errorf("container is paused"), ContainerPaused)
}
-// restoredState is the same as the running state but also has accociated checkpoint
-// information that maybe need destroyed when the container is stopped and destory is called.
+// restoredState is the same as the running state but also has associated checkpoint
+// information that maybe need destroyed when the container is stopped and destroy is called.
type restoredState struct {
imageDir string
c *linuxContainer
@@ -187,9 +208,7 @@ func (r *restoredState) status() Status {
func (r *restoredState) transition(s containerState) error {
switch s.(type) {
- case *stoppedState:
- return nil
- case *runningState:
+ case *stoppedState, *runningState:
return nil
}
return newStateTransitionError(r, s)
@@ -204,23 +223,23 @@ func (r *restoredState) destroy() error {
return destroy(r.c)
}
-// createdState is used whenever a container is restored, loaded, or setting additional
+// loadedState is used whenever a container is restored, loaded, or setting additional
// processes inside and it should not be destroyed when it is exiting.
-type createdState struct {
+type loadedState struct {
c *linuxContainer
s Status
}
-func (n *createdState) status() Status {
+func (n *loadedState) status() Status {
return n.s
}
-func (n *createdState) transition(s containerState) error {
+func (n *loadedState) transition(s containerState) error {
n.c.state = s
return nil
}
-func (n *createdState) destroy() error {
+func (n *loadedState) destroy() error {
if err := n.c.refreshState(); err != nil {
return err
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/state_linux_test.go b/vendor/github.com/opencontainers/runc/libcontainer/state_linux_test.go
index 417d9c22..cadacbe0 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/state_linux_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/state_linux_test.go
@@ -6,10 +6,11 @@ import "testing"
func TestStateStatus(t *testing.T) {
states := map[containerState]Status{
- &stoppedState{}: Destroyed,
+ &stoppedState{}: Stopped,
&runningState{}: Running,
&restoredState{}: Running,
&pausedState{}: Paused,
+ &createdState{}: Created,
}
for s, status := range states {
if s.status() != status {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/stats_solaris.go b/vendor/github.com/opencontainers/runc/libcontainer/stats_solaris.go
new file mode 100644
index 00000000..da78c1c2
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/stats_solaris.go
@@ -0,0 +1,7 @@
+package libcontainer
+
+// Solaris - TODO
+
+type Stats struct {
+ Interfaces []*NetworkInterface
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/sync.go b/vendor/github.com/opencontainers/runc/libcontainer/sync.go
new file mode 100644
index 00000000..4016cd0d
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/sync.go
@@ -0,0 +1,110 @@
+package libcontainer
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+
+ "github.com/opencontainers/runc/libcontainer/utils"
+)
+
+type syncType string
+
+// Constants that are used for synchronisation between the parent and child
+// during container setup. They come in pairs (with procError being a generic
+// response which is followed by a &genericError).
+//
+// [ child ] <-> [ parent ]
+//
+// procHooks --> [run hooks]
+// <-- procResume
+//
+// procConsole -->
+// <-- procConsoleReq
+// [send(fd)] --> [recv(fd)]
+// <-- procConsoleAck
+//
+// procReady --> [final setup]
+// <-- procRun
+const (
+ procError syncType = "procError"
+ procReady syncType = "procReady"
+ procRun syncType = "procRun"
+ procHooks syncType = "procHooks"
+ procResume syncType = "procResume"
+ procConsole syncType = "procConsole"
+ procConsoleReq syncType = "procConsoleReq"
+ procConsoleAck syncType = "procConsoleAck"
+)
+
+type syncT struct {
+ Type syncType `json:"type"`
+}
+
+// writeSync is used to write to a synchronisation pipe. An error is returned
+// if there was a problem writing the payload.
+func writeSync(pipe io.Writer, sync syncType) error {
+ if err := utils.WriteJSON(pipe, syncT{sync}); err != nil {
+ return err
+ }
+ return nil
+}
+
+// readSync is used to read from a synchronisation pipe. An error is returned
+// if we got a genericError, the pipe was closed, or we got an unexpected flag.
+func readSync(pipe io.Reader, expected syncType) error {
+ var procSync syncT
+ if err := json.NewDecoder(pipe).Decode(&procSync); err != nil {
+ if err == io.EOF {
+ return fmt.Errorf("parent closed synchronisation channel")
+ }
+
+ if procSync.Type == procError {
+ var ierr genericError
+
+ if err := json.NewDecoder(pipe).Decode(&ierr); err != nil {
+ return fmt.Errorf("failed reading error from parent: %v", err)
+ }
+
+ return &ierr
+ }
+
+ if procSync.Type != expected {
+ return fmt.Errorf("invalid synchronisation flag from parent")
+ }
+ }
+ return nil
+}
+
+// parseSync runs the given callback function on each syncT received from the
+// child. It will return once io.EOF is returned from the given pipe.
+func parseSync(pipe io.Reader, fn func(*syncT) error) error {
+ dec := json.NewDecoder(pipe)
+ for {
+ var sync syncT
+ if err := dec.Decode(&sync); err != nil {
+ if err == io.EOF {
+ break
+ }
+ return err
+ }
+
+ // We handle this case outside fn for cleanliness reasons.
+ var ierr *genericError
+ if sync.Type == procError {
+ if err := dec.Decode(&ierr); err != nil && err != io.EOF {
+ return newSystemErrorWithCause(err, "decoding proc error from init")
+ }
+ if ierr != nil {
+ return ierr
+ }
+ // Programmer error.
+ panic("No error following JSON procError payload.")
+ }
+
+ if err := fn(&sync); err != nil {
+ return err
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/linux.go b/vendor/github.com/opencontainers/runc/libcontainer/system/linux.go
index 8b199d92..1afc52b4 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/system/linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/system/linux.go
@@ -100,17 +100,12 @@ func Setctty() error {
return nil
}
-/*
- * Detect whether we are currently running in a user namespace.
- * Copied from github.com/lxc/lxd/shared/util.go
- */
+// RunningInUserNS detects whether we are currently running in a user namespace.
+// Copied from github.com/lxc/lxd/shared/util.go
func RunningInUserNS() bool {
file, err := os.Open("/proc/self/uid_map")
if err != nil {
- /*
- * This kernel-provided file only exists if user namespaces are
- * supported
- */
+ // This kernel-provided file only exists if user namespaces are supported
return false
}
defer file.Close()
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/proc.go b/vendor/github.com/opencontainers/runc/libcontainer/system/proc.go
index 37808a29..a0e96371 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/system/proc.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/system/proc.go
@@ -14,8 +14,10 @@ func GetProcessStartTime(pid int) (string, error) {
if err != nil {
return "", err
}
+ return parseStartTime(string(data))
+}
- parts := strings.Split(string(data), " ")
+func parseStartTime(stat string) (string, error) {
// the starttime is located at pos 22
// from the man page
//
@@ -23,5 +25,19 @@ func GetProcessStartTime(pid int) (string, error) {
// (22) The time the process started after system boot. In kernels before Linux 2.6, this
// value was expressed in jiffies. Since Linux 2.6, the value is expressed in clock ticks
// (divide by sysconf(_SC_CLK_TCK)).
- return parts[22-1], nil // starts at 1
+ //
+ // NOTE:
+ // pos 2 could contain space and is inside `(` and `)`:
+ // (2) comm %s
+ // The filename of the executable, in parentheses.
+ // This is visible whether or not the executable is
+ // swapped out.
+ //
+ // the following is an example:
+ // 89653 (gunicorn: maste) S 89630 89653 89653 0 -1 4194560 29689 28896 0 3 146 32 76 19 20 0 1 0 2971844 52965376 3920 18446744073709551615 1 1 0 0 0 0 0 16781312 137447943 0 0 0 17 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+
+ // get parts after last `)`:
+ s := strings.Split(stat, ")")
+ parts := strings.Split(strings.TrimSpace(s[len(s)-1]), " ")
+ return parts[22-3], nil // starts at 3 (after the filename pos `2`)
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/proc_test.go b/vendor/github.com/opencontainers/runc/libcontainer/system/proc_test.go
new file mode 100644
index 00000000..ba910291
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/system/proc_test.go
@@ -0,0 +1,20 @@
+package system
+
+import "testing"
+
+func TestParseStartTime(t *testing.T) {
+ data := map[string]string{
+ "4902 (gunicorn: maste) S 4885 4902 4902 0 -1 4194560 29683 29929 61 83 78 16 96 17 20 0 1 0 9126532 52965376 1903 18446744073709551615 4194304 7461796 140733928751520 140733928698072 139816984959091 0 0 16781312 137447943 1 0 0 17 3 0 0 9 0 0 9559488 10071156 33050624 140733928758775 140733928758945 140733928758945 140733928759264 0": "9126532",
+ "9534 (cat) R 9323 9534 9323 34828 9534 4194304 95 0 0 0 0 0 0 0 20 0 1 0 9214966 7626752 168 18446744073709551615 4194304 4240332 140732237651568 140732237650920 140570710391216 0 0 0 0 0 0 0 17 1 0 0 0 0 0 6340112 6341364 21553152 140732237653865 140732237653885 140732237653885 140732237656047 0": "9214966",
+ "24767 (irq/44-mei_me) S 2 0 0 0 -1 2129984 0 0 0 0 0 0 0 0 -51 0 1 0 8722075 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 0 0 0 17 1 50 1 0 0 0 0 0 0 0 0 0 0 0": "8722075",
+ }
+ for line, startTime := range data {
+ st, err := parseStartTime(line)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if startTime != st {
+ t.Fatalf("expected start time %q but received %q", startTime, st)
+ }
+ }
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_386.go b/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_386.go
index c9900651..bb44d895 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_386.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_386.go
@@ -8,7 +8,7 @@ import (
// Setuid sets the uid of the calling thread to the specified uid.
func Setuid(uid int) (err error) {
- _, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID, uintptr(uid), 0, 0)
+ _, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID32, uintptr(uid), 0, 0)
if e1 != 0 {
err = e1
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/user.go b/vendor/github.com/opencontainers/runc/libcontainer/user/user.go
index 43fd39ef..f258d624 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/user/user.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/user/user.go
@@ -343,7 +343,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (
if len(groups) > 0 {
// First match wins, even if there's more than one matching entry.
user.Gid = groups[0].Gid
- } else if groupArg != "" {
+ } else {
// If we can't find a group with the given name, the only other valid
// option is if it's a numeric group name with no associated entry in group.
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/user_test.go b/vendor/github.com/opencontainers/runc/libcontainer/user/user_test.go
index 8cad2f55..24ee559e 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/user/user_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/user/user_test.go
@@ -7,6 +7,8 @@ import (
"strconv"
"strings"
"testing"
+
+ "github.com/opencontainers/runc/libcontainer/utils"
)
func TestUserParseLine(t *testing.T) {
@@ -382,6 +384,12 @@ this is just some garbage data
}
func TestGetAdditionalGroups(t *testing.T) {
+ type foo struct {
+ groups []string
+ expected []int
+ hasError bool
+ }
+
const groupContent = `
root:x:0:root
adm:x:43:
@@ -389,11 +397,7 @@ grp:x:1234:root,adm
adm:x:4343:root,adm-duplicate
this is just some garbage data
`
- tests := []struct {
- groups []string
- expected []int
- hasError bool
- }{
+ tests := []foo{
{
// empty group
groups: []string{},
@@ -436,12 +440,15 @@ this is just some garbage data
expected: nil,
hasError: true,
},
- {
+ }
+
+ if utils.GetIntSize() > 4 {
+ tests = append(tests, foo{
// groups with too large id
groups: []string{strconv.Itoa(1 << 31)},
expected: nil,
hasError: true,
- },
+ })
}
for _, test := range tests {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.c b/vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.c
new file mode 100644
index 00000000..0ded4944
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2016 SUSE LLC
+ *
+ * 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.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "cmsg.h"
+
+#define error(fmt, ...) \
+ ({ \
+ fprintf(stderr, "nsenter: " fmt ": %m\n", ##__VA_ARGS__); \
+ errno = ECOMM; \
+ goto err; /* return value */ \
+ })
+
+/*
+ * Sends a file descriptor along the sockfd provided. Returns the return
+ * value of sendmsg(2). Any synchronisation and preparation of state
+ * should be done external to this (we expect the other side to be in
+ * recvfd() in the code).
+ */
+ssize_t sendfd(int sockfd, struct file_t file)
+{
+ struct msghdr msg = {0};
+ struct iovec iov[1] = {0};
+ struct cmsghdr *cmsg;
+ int *fdptr;
+ int ret;
+
+ union {
+ char buf[CMSG_SPACE(sizeof(file.fd))];
+ struct cmsghdr align;
+ } u;
+
+ /*
+ * We need to send some other data along with the ancillary data,
+ * otherwise the other side won't recieve any data. This is very
+ * well-hidden in the documentation (and only applies to
+ * SOCK_STREAM). See the bottom part of unix(7).
+ */
+ iov[0].iov_base = file.name;
+ iov[0].iov_len = strlen(file.name) + 1;
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = u.buf;
+ msg.msg_controllen = sizeof(u.buf);
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+
+ fdptr = (int *) CMSG_DATA(cmsg);
+ memcpy(fdptr, &file.fd, sizeof(int));
+
+ return sendmsg(sockfd, &msg, 0);
+}
+
+/*
+ * Receives a file descriptor from the sockfd provided. Returns the file
+ * descriptor as sent from sendfd(). It will return the file descriptor
+ * or die (literally) trying. Any synchronisation and preparation of
+ * state should be done external to this (we expect the other side to be
+ * in sendfd() in the code).
+ */
+struct file_t recvfd(int sockfd)
+{
+ struct msghdr msg = {0};
+ struct iovec iov[1] = {0};
+ struct cmsghdr *cmsg;
+ struct file_t file = {0};
+ int *fdptr;
+ int olderrno;
+
+ union {
+ char buf[CMSG_SPACE(sizeof(file.fd))];
+ struct cmsghdr align;
+ } u;
+
+ /* Allocate a buffer. */
+ /* TODO: Make this dynamic with MSG_PEEK. */
+ file.name = malloc(TAG_BUFFER);
+ if (!file.name)
+ error("recvfd: failed to allocate file.tag buffer\n");
+
+ /*
+ * We need to "recieve" the non-ancillary data even though we don't
+ * plan to use it at all. Otherwise, things won't work as expected.
+ * See unix(7) and other well-hidden documentation.
+ */
+ iov[0].iov_base = file.name;
+ iov[0].iov_len = TAG_BUFFER;
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = u.buf;
+ msg.msg_controllen = sizeof(u.buf);
+
+ ssize_t ret = recvmsg(sockfd, &msg, 0);
+ if (ret < 0)
+ goto err;
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (!cmsg)
+ error("recvfd: got NULL from CMSG_FIRSTHDR");
+ if (cmsg->cmsg_level != SOL_SOCKET)
+ error("recvfd: expected SOL_SOCKET in cmsg: %d", cmsg->cmsg_level);
+ if (cmsg->cmsg_type != SCM_RIGHTS)
+ error("recvfd: expected SCM_RIGHTS in cmsg: %d", cmsg->cmsg_type);
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)))
+ error("recvfd: expected correct CMSG_LEN in cmsg: %lu", (unsigned long)cmsg->cmsg_len);
+
+ fdptr = (int *) CMSG_DATA(cmsg);
+ if (!fdptr || *fdptr < 0)
+ error("recvfd: recieved invalid pointer");
+
+ file.fd = *fdptr;
+ return file;
+
+err:
+ olderrno = errno;
+ free(file.name);
+ errno = olderrno;
+ return (struct file_t){0};
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.go b/vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.go
new file mode 100644
index 00000000..ee893741
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.go
@@ -0,0 +1,57 @@
+// +build linux
+
+package utils
+
+/*
+ * Copyright 2016 SUSE LLC
+ *
+ * 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.
+ */
+
+/*
+#include
+#include
+#include "cmsg.h"
+*/
+import "C"
+
+import (
+ "os"
+ "unsafe"
+)
+
+// 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 *os.File) (*os.File, error) {
+ file, err := C.recvfd(C.int(socket.Fd()))
+ if err != nil {
+ return nil, err
+ }
+ defer C.free(unsafe.Pointer(file.name))
+ return os.NewFile(uintptr(file.fd), C.GoString(file.name)), nil
+}
+
+// SendFd sends a file descriptor over the given AF_UNIX socket. In
+// addition, the file.Name() of the given file will also be sent as
+// non-auxiliary data in the same payload (allowing to send contextual
+// information for a file descriptor).
+func SendFd(socket, file *os.File) error {
+ var cfile C.struct_file_t
+ cfile.fd = C.int(file.Fd())
+ cfile.name = C.CString(file.Name())
+ defer C.free(unsafe.Pointer(cfile.name))
+
+ _, err := C.sendfd(C.int(socket.Fd()), cfile)
+ return err
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.h b/vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.h
new file mode 100644
index 00000000..3fe76425
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2016 SUSE LLC
+ *
+ * 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.
+ */
+
+#pragma once
+
+#if !defined(CMSG_H)
+#define CMSG_H
+
+#include
+
+/* TODO: Implement this properly with MSG_PEEK. */
+#define TAG_BUFFER 4096
+
+/* This mirrors Go's (*os.File). */
+struct file_t {
+ char *name;
+ int fd;
+};
+
+struct file_t recvfd(int sockfd);
+ssize_t sendfd(int sockfd, struct file_t file);
+
+#endif /* !defined(CMSG_H) */
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go b/vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go
index 9e748a6d..2b35b9a7 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go
@@ -9,6 +9,7 @@ import (
"path/filepath"
"strings"
"syscall"
+ "unsafe"
)
const (
@@ -100,3 +101,26 @@ func SearchLabels(labels []string, query string) string {
}
return ""
}
+
+// Annotations returns the bundle path and user defined annotations from the
+// libcontainer state. We need to remove the bundle because that is a label
+// added by libcontainer.
+func Annotations(labels []string) (bundle string, userAnnotations map[string]string) {
+ userAnnotations = make(map[string]string)
+ for _, l := range labels {
+ parts := strings.SplitN(l, "=", 2)
+ if len(parts) < 2 {
+ continue
+ }
+ if parts[0] == "bundle" {
+ bundle = parts[1]
+ } else {
+ userAnnotations[parts[0]] = parts[1]
+ }
+ }
+ return
+}
+
+func GetIntSize() int {
+ return int(unsafe.Sizeof(1))
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/utils/utils_test.go b/vendor/github.com/opencontainers/runc/libcontainer/utils/utils_test.go
index 6bb0d677..b7746829 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/utils/utils_test.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/utils/utils_test.go
@@ -133,21 +133,21 @@ func TestWriteJSON(t *testing.T) {
func TestCleanPath(t *testing.T) {
path := CleanPath("")
if path != "" {
- t.Errorf("expected to received empty string and received %s", path)
+ t.Errorf("expected to receive empty string and received %s", path)
}
path = CleanPath("rootfs")
if path != "rootfs" {
- t.Errorf("expected to received 'rootfs' and received %s", path)
+ t.Errorf("expected to receive 'rootfs' and received %s", path)
}
path = CleanPath("../../../var")
if path != "var" {
- t.Errorf("expected to received 'var' and received %s", path)
+ t.Errorf("expected to receive 'var' and received %s", path)
}
path = CleanPath("/../../../var")
if path != "/var" {
- t.Errorf("expected to received '/var' and received %s", path)
+ t.Errorf("expected to receive '/var' and received %s", path)
}
}
diff --git a/vendor/github.com/opencontainers/runc/list.go b/vendor/github.com/opencontainers/runc/list.go
index 1750ef81..c7550a2a 100644
--- a/vendor/github.com/opencontainers/runc/list.go
+++ b/vendor/github.com/opencontainers/runc/list.go
@@ -12,8 +12,9 @@ import (
"encoding/json"
- "github.com/codegangsta/cli"
+ "github.com/opencontainers/runc/libcontainer"
"github.com/opencontainers/runc/libcontainer/utils"
+ "github.com/urfave/cli"
)
const formatOptions = `table or json`
@@ -21,6 +22,8 @@ const formatOptions = `table or json`
// containerState represents the platform agnostic pieces relating to a
// running container's status and state
type containerState struct {
+ // Version is the OCI version for the container
+ Version string `json:"ociVersion"`
// ID is the container ID
ID string `json:"id"`
// InitProcessPid is the init process id in the parent namespace
@@ -29,33 +32,58 @@ type containerState struct {
Status string `json:"status"`
// Bundle is the path on the filesystem to the bundle
Bundle string `json:"bundle"`
+ // Rootfs is a path to a directory containing the container's root filesystem.
+ Rootfs string `json:"rootfs"`
// Created is the unix timestamp for the creation time of the container in UTC
Created time.Time `json:"created"`
+ // Annotations is the user defined annotations added to the config.
+ Annotations map[string]string `json:"annotations,omitempty"`
}
var listCommand = cli.Command{
Name: "list",
Usage: "lists containers started by runc with the given root",
+ ArgsUsage: `
+
+Where the given root is specified via the global option "--root"
+(default: "/run/runc").
+
+EXAMPLE 1:
+To list containers created via the default "--root":
+ # runc list
+
+EXAMPLE 2:
+To list containers created using a non-default value for "--root":
+ # runc --root value list`,
Flags: []cli.Flag{
cli.StringFlag{
Name: "format, f",
- Value: "",
- Usage: `select one of: ` + formatOptions + `.
-
-The default format is table. The following will output the list of containers
-in json format:
-
- # runc list -f json`,
+ Value: "table",
+ Usage: `select one of: ` + formatOptions,
+ },
+ cli.BoolFlag{
+ Name: "quiet, q",
+ Usage: "display only container IDs",
},
},
- Action: func(context *cli.Context) {
+ Action: func(context *cli.Context) error {
+ if err := checkArgs(context, 0, exactArgs); err != nil {
+ return err
+ }
s, err := getContainers(context)
if err != nil {
- fatal(err)
+ return err
+ }
+
+ if context.Bool("quiet") {
+ for _, item := range s {
+ fmt.Println(item.ID)
+ }
+ return nil
}
switch context.String("format") {
- case "", "table":
+ case "table":
w := tabwriter.NewWriter(os.Stdout, 12, 1, 3, ' ', 0)
fmt.Fprint(w, "ID\tPID\tSTATUS\tBUNDLE\tCREATED\n")
for _, item := range s {
@@ -67,18 +95,16 @@ in json format:
item.Created.Format(time.RFC3339Nano))
}
if err := w.Flush(); err != nil {
- fatal(err)
+ return err
}
case "json":
- data, err := json.Marshal(s)
- if err != nil {
- fatal(err)
+ if err := json.NewEncoder(os.Stdout).Encode(s); err != nil {
+ return err
}
- os.Stdout.Write(data)
-
default:
- fatalf("invalid format option")
+ return fmt.Errorf("invalid format option")
}
+ return nil
},
}
@@ -102,22 +128,34 @@ func getContainers(context *cli.Context) ([]containerState, error) {
if item.IsDir() {
container, err := factory.Load(item.Name())
if err != nil {
- return nil, err
+ fmt.Fprintf(os.Stderr, "load container %s: %v\n", item.Name(), err)
+ continue
}
containerStatus, err := container.Status()
if err != nil {
- return nil, err
+ fmt.Fprintf(os.Stderr, "status for %s: %v\n", item.Name(), err)
+ continue
}
state, err := container.State()
if err != nil {
- return nil, err
+ fmt.Fprintf(os.Stderr, "state for %s: %v\n", item.Name(), err)
+ continue
}
+ pid := state.BaseState.InitProcessPid
+ if containerStatus == libcontainer.Stopped {
+ pid = 0
+ }
+ bundle, annotations := utils.Annotations(state.Config.Labels)
s = append(s, containerState{
+ Version: state.BaseState.Config.Version,
ID: state.BaseState.ID,
- InitProcessPid: state.BaseState.InitProcessPid,
+ InitProcessPid: pid,
Status: containerStatus.String(),
- Bundle: utils.SearchLabels(state.Config.Labels, "bundle"),
- Created: state.BaseState.Created})
+ Bundle: bundle,
+ Rootfs: state.BaseState.Config.Rootfs,
+ Created: state.BaseState.Created,
+ Annotations: annotations,
+ })
}
}
return s, nil
diff --git a/vendor/github.com/opencontainers/runc/main.go b/vendor/github.com/opencontainers/runc/main.go
index 3524937f..1cb8f4db 100644
--- a/vendor/github.com/opencontainers/runc/main.go
+++ b/vendor/github.com/opencontainers/runc/main.go
@@ -2,25 +2,29 @@ package main
import (
"fmt"
+ "io"
"os"
"strings"
"github.com/Sirupsen/logrus"
- "github.com/codegangsta/cli"
"github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/urfave/cli"
)
+// version will be populated by the Makefile, read from
+// VERSION file of the source code.
+var version = ""
+
// gitCommit will be the hash that the binary was built from
// and will be populated by the Makefile
var gitCommit = ""
const (
- version = "0.1.1"
specConfig = "config.json"
usage = `Open Container Initiative runtime
-
+
runc is a command line client for running applications packaged according to
-the Open Container Format (OCF) and is a compliant implementation of the
+the Open Container Initiative (OCI) format and is a compliant implementation of the
Open Container Initiative specification.
runc integrates well with existing process supervisors to provide a production
@@ -30,11 +34,11 @@ direct child of the process supervisor.
Containers are configured using bundles. A bundle for a container is a directory
that includes a specification file named "` + specConfig + `" and a root filesystem.
-The root filesystem contains the contents of the container.
+The root filesystem contains the contents of the container.
To start a new instance of a container:
- # runc start [ -b bundle ]
+ # runc run [ -b bundle ]
Where "" is your name for the instance of the container that you
are starting. The name you provide for the container instance must be unique on
@@ -46,8 +50,10 @@ func main() {
app := cli.NewApp()
app.Name = "runc"
app.Usage = usage
- v := []string{
- version,
+
+ var v []string
+ if version != "" {
+ v = append(v, version)
}
if gitCommit != "" {
v = append(v, fmt.Sprintf("commit: %s", gitCommit))
@@ -86,6 +92,7 @@ func main() {
}
app.Commands = []cli.Command{
checkpointCommand,
+ createCommand,
deleteCommand,
eventsCommand,
execCommand,
@@ -93,11 +100,14 @@ func main() {
killCommand,
listCommand,
pauseCommand,
+ psCommand,
restoreCommand,
resumeCommand,
+ runCommand,
specCommand,
startCommand,
stateCommand,
+ updateCommand,
}
app.Before = func(context *cli.Context) error {
if context.GlobalBool("debug") {
@@ -116,11 +126,24 @@ func main() {
case "json":
logrus.SetFormatter(new(logrus.JSONFormatter))
default:
- logrus.Fatalf("unknown log-format %q", context.GlobalString("log-format"))
+ return fmt.Errorf("unknown log-format %q", context.GlobalString("log-format"))
}
return nil
}
+ // If the command returns an error, cli takes upon itself to print
+ // the error on cli.ErrWriter and exit.
+ // Use our own writer here to ensure the log gets sent to the right location.
+ cli.ErrWriter = &FatalWriter{cli.ErrWriter}
if err := app.Run(os.Args); err != nil {
fatal(err)
}
}
+
+type FatalWriter struct {
+ cliErrWriter io.Writer
+}
+
+func (f *FatalWriter) Write(p []byte) (n int, err error) {
+ logrus.Error(string(p))
+ return f.cliErrWriter.Write(p)
+}
diff --git a/vendor/github.com/opencontainers/runc/main_solaris.go b/vendor/github.com/opencontainers/runc/main_solaris.go
new file mode 100644
index 00000000..3c365db1
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/main_solaris.go
@@ -0,0 +1,21 @@
+// +build solaris
+
+package main
+
+import "github.com/urfave/cli"
+
+var (
+ checkpointCommand cli.Command
+ eventsCommand cli.Command
+ restoreCommand cli.Command
+ specCommand cli.Command
+ killCommand cli.Command
+ deleteCommand cli.Command
+ execCommand cli.Command
+ initCommand cli.Command
+ listCommand cli.Command
+ pauseCommand cli.Command
+ resumeCommand cli.Command
+ startCommand cli.Command
+ stateCommand cli.Command
+)
diff --git a/vendor/github.com/opencontainers/runc/main_unix.go b/vendor/github.com/opencontainers/runc/main_unix.go
index 7bbec9fa..b601abc7 100644
--- a/vendor/github.com/opencontainers/runc/main_unix.go
+++ b/vendor/github.com/opencontainers/runc/main_unix.go
@@ -2,4 +2,32 @@
package main
-import _ "github.com/opencontainers/runc/libcontainer/nsenter"
+import (
+ "os"
+ "runtime"
+
+ "github.com/opencontainers/runc/libcontainer"
+ _ "github.com/opencontainers/runc/libcontainer/nsenter"
+ "github.com/urfave/cli"
+)
+
+func init() {
+ if len(os.Args) > 1 && os.Args[1] == "init" {
+ runtime.GOMAXPROCS(1)
+ runtime.LockOSThread()
+ }
+}
+
+var initCommand = cli.Command{
+ Name: "init",
+ Usage: `initialize the namespaces and launch the process (do not call it outside of runc)`,
+ Action: func(context *cli.Context) error {
+ factory, _ := libcontainer.New("")
+ if err := factory.StartInitialization(); err != nil {
+ // as the error is sent back to the parent there is no need to log
+ // or write it to stderr because the parent process will handle this
+ os.Exit(1)
+ }
+ panic("libcontainer: container init failed to exec")
+ },
+}
diff --git a/vendor/github.com/opencontainers/runc/main_unsupported.go b/vendor/github.com/opencontainers/runc/main_unsupported.go
index 32ce1ac9..4d69931a 100644
--- a/vendor/github.com/opencontainers/runc/main_unsupported.go
+++ b/vendor/github.com/opencontainers/runc/main_unsupported.go
@@ -1,8 +1,8 @@
-// +build !linux
+// +build !linux,!solaris
package main
-import "github.com/codegangsta/cli"
+import "github.com/urfave/cli"
var (
checkpointCommand cli.Command
diff --git a/vendor/github.com/opencontainers/runc/man/runc-checkpoint.8.md b/vendor/github.com/opencontainers/runc/man/runc-checkpoint.8.md
index 6dc7b889..632dcabb 100644
--- a/vendor/github.com/opencontainers/runc/man/runc-checkpoint.8.md
+++ b/vendor/github.com/opencontainers/runc/man/runc-checkpoint.8.md
@@ -1,7 +1,7 @@
# NAME
runc checkpoint - checkpoint a running container
-# USAGE
+# SYNOPSIS
runc checkpoint [command options]
Where "" is the name for the instance of the container to be
@@ -11,12 +11,13 @@ checkpointed.
The checkpoint command saves the state of the container instance.
# OPTIONS
- --image-path path for saving criu image files
- --work-path path for saving work files and logs
+ --image-path value path for saving criu image files
+ --work-path value path for saving work files and logs
--leave-running leave the process running after checkpointing
--tcp-established allow open tcp connections
--ext-unix-sk allow external unix sockets
--shell-job allow shell jobs
- --page-server ADDRESS:PORT of the page server
+ --page-server value ADDRESS:PORT of the page server
--file-locks handle file locks, for safety
- --manage-cgroups-mode cgroups mode: 'soft' (default), 'full' and 'strict'.
+ --manage-cgroups-mode value cgroups mode: 'soft' (default), 'full' and 'strict'
+ --empty-ns value create a namespace, but don't restore its properies
diff --git a/vendor/github.com/opencontainers/runc/man/runc-create.8.md b/vendor/github.com/opencontainers/runc/man/runc-create.8.md
new file mode 100644
index 00000000..c70217b8
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/man/runc-create.8.md
@@ -0,0 +1,26 @@
+# NAME
+ runc create - create a container
+
+# SYNOPSIS
+ runc create [command options]
+
+Where "" is your name for the instance of the container that you
+are starting. The name you provide for the container instance must be unique on
+your host.
+
+# DESCRIPTION
+ The create command creates an instance of a container for a bundle. The bundle
+is a directory with a specification file named "config.json" and a root
+filesystem.
+
+The specification file includes an args parameter. The args parameter is used
+to specify command(s) that get run when the container is started. To change the
+command(s) that get executed on start, edit the args parameter of the spec. See
+"runc spec --help" for more explanation.
+
+# OPTIONS
+ --bundle value, -b value path to the root of the bundle directory, defaults to the current directory
+ --console value specify the pty slave path for use with the container
+ --pid-file value specify the file to write the process id to
+ --no-pivot do not use pivot root to jail process inside rootfs. This should be used whenever the rootfs is on top of a ramdisk
+ --no-new-keyring do not create a new session keyring for the container. This will cause the container to inherit the calling processes session key
diff --git a/vendor/github.com/opencontainers/runc/man/runc-delete.8.md b/vendor/github.com/opencontainers/runc/man/runc-delete.8.md
index 1ea021e1..12ea711b 100644
--- a/vendor/github.com/opencontainers/runc/man/runc-delete.8.md
+++ b/vendor/github.com/opencontainers/runc/man/runc-delete.8.md
@@ -1,14 +1,17 @@
# NAME
- runc delete - delete any resources held by the container often used with detached containers
+ runc delete - delete any resources held by one or more containers often used with detached containers
# SYNOPSIS
- runc delete
+ runc delete [command options] [container-id...]
Where "" is the name for the instance of the container.
+# OPTIONS
+ --force, -f Forcibly deletes the container if it is still running (uses SIGKILL)
+
# EXAMPLE
For example, if the container id is "ubuntu01" and runc list currently shows the
-status of "ubuntu01" as "destroyed" the following will delete resources held for
+status of "ubuntu01" as "stopped" the following will delete resources held for
"ubuntu01" removing "ubuntu01" from the runc list of containers:
# runc delete ubuntu01
diff --git a/vendor/github.com/opencontainers/runc/man/runc-events.8.md b/vendor/github.com/opencontainers/runc/man/runc-events.8.md
index 10385e9b..2f7bb0ea 100644
--- a/vendor/github.com/opencontainers/runc/man/runc-events.8.md
+++ b/vendor/github.com/opencontainers/runc/man/runc-events.8.md
@@ -1,5 +1,5 @@
# NAME
- runc events - display container events such as OOM notifications, cpu, memory, IO and network stats
+ runc events - display container events such as OOM notifications, cpu, memory, and IO usage statistics
# SYNOPSIS
runc events [command options]
@@ -11,6 +11,5 @@ Where "" is the name for the instance of the container.
information is displayed once every 5 seconds.
# OPTIONS
- --interval "5s" set the stats collection interval
+ --interval value set the stats collection interval (default: 5s)
--stats display the container's stats then exit
-
diff --git a/vendor/github.com/opencontainers/runc/man/runc-exec.8.md b/vendor/github.com/opencontainers/runc/man/runc-exec.8.md
index d75db78b..e47f8284 100644
--- a/vendor/github.com/opencontainers/runc/man/runc-exec.8.md
+++ b/vendor/github.com/opencontainers/runc/man/runc-exec.8.md
@@ -2,7 +2,7 @@
runc exec - execute new process inside the container
# SYNOPSIS
- runc exec [command options]
+ runc exec [command options] -- [args...]
Where "" is the name for the instance of the container and
"" is the command to be executed in the container.
@@ -14,15 +14,16 @@ following will output a list of processes running in the container:
# runc exec ps
# OPTIONS
- --console specify the pty slave path for use with the container
- --cwd current working directory in the container
- --env, -e [--env option --env option] set environment variables
- --tty, -t allocate a pseudo-TTY
- --user, -u UID (format: [:])
- --process, -p path to the process.json
- --detach, -d detach from the container's process
- --pid-file specify the file to write the process id to
- --process-label set the asm process label for the process commonly used with selinux
- --apparmor set the apparmor profile for the process
- --no-new-privs set the no new privileges value for the process
- --cap, -c [--cap option --cap option] add a capability to the bounding set for the process
+ --console value specify the pty slave path for use with the container
+ --cwd value current working directory in the container
+ --env value, -e value set environment variables
+ --tty, -t allocate a pseudo-TTY
+ --user value, -u value UID (format: [:])
+ --process value, -p value path to the process.json
+ --detach, -d detach from the container's process
+ --pid-file value specify the file to write the process id to
+ --process-label value set the asm process label for the process commonly used with selinux
+ --apparmor value set the apparmor profile for the process
+ --no-new-privs set the no new privileges value for the process
+ --cap value, -c value add a capability to the bounding set for the process
+ --no-subreaper disable the use of the subreaper used to reap reparented processes
diff --git a/vendor/github.com/opencontainers/runc/man/runc-kill.8.md b/vendor/github.com/opencontainers/runc/man/runc-kill.8.md
index 65642d64..3566e5f3 100644
--- a/vendor/github.com/opencontainers/runc/man/runc-kill.8.md
+++ b/vendor/github.com/opencontainers/runc/man/runc-kill.8.md
@@ -2,11 +2,14 @@
runc kill - kill sends the specified signal (default: SIGTERM) to the container's init process
# SYNOPSIS
- runc kill
+ runc kill [command options]
Where "" is the name for the instance of the container and
"" is the signal to be sent to the init process.
+# OPTIONS
+ --all, -a send the specified signal to all processes inside the container
+
# EXAMPLE
For example, if the container id is "ubuntu01" the following will send a "KILL"
diff --git a/vendor/github.com/opencontainers/runc/man/runc-list.8.md b/vendor/github.com/opencontainers/runc/man/runc-list.8.md
index c7ab0f60..f7374244 100644
--- a/vendor/github.com/opencontainers/runc/man/runc-list.8.md
+++ b/vendor/github.com/opencontainers/runc/man/runc-list.8.md
@@ -2,13 +2,18 @@
runc list - lists containers started by runc with the given root
# SYNOPSIS
- runc list [command options] [arguments...]
+ runc list [command options]
-# DESCRIPTION
- The default format is table. The following will output the list of containers
-in json format:
+# EXAMPLE
+Where the given root is specified via the global option "--root"
+(default: "/run/runc").
- # runc list -f json
+To list containers created via the default "--root":
+ # runc list
+
+To list containers created using a non-default value for "--root":
+ # runc --root value list
# OPTIONS
- --format, -f select one of: table or json.
+ --format value, -f value select one of: table or json (default: "table")
+ --quiet, -q display only container IDs
diff --git a/vendor/github.com/opencontainers/runc/man/runc-pause.8.md b/vendor/github.com/opencontainers/runc/man/runc-pause.8.md
index 4a4265e8..489bb907 100644
--- a/vendor/github.com/opencontainers/runc/man/runc-pause.8.md
+++ b/vendor/github.com/opencontainers/runc/man/runc-pause.8.md
@@ -2,7 +2,7 @@
runc pause - pause suspends all processes inside the container
# SYNOPSIS
- runc pause
+ runc pause [container-id...]
Where "" is the name for the instance of the container to be
paused.
diff --git a/vendor/github.com/opencontainers/runc/man/runc-ps.8.md b/vendor/github.com/opencontainers/runc/man/runc-ps.8.md
new file mode 100644
index 00000000..d6063471
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/man/runc-ps.8.md
@@ -0,0 +1,13 @@
+# NAME
+ runc ps - ps displays the processes running inside a container
+
+# SYNOPSIS
+ runc ps [command options] [-- ps options]
+
+# OPTIONS
+ --format value, -f value select one of: table(default) or json
+
+The default format is table. The following will output the processes of a container
+in json format:
+
+ # runc ps -f json
diff --git a/vendor/github.com/opencontainers/runc/man/runc-restore.8.md b/vendor/github.com/opencontainers/runc/man/runc-restore.8.md
index b0dec455..1793fb55 100644
--- a/vendor/github.com/opencontainers/runc/man/runc-restore.8.md
+++ b/vendor/github.com/opencontainers/runc/man/runc-restore.8.md
@@ -12,13 +12,15 @@ restored.
using the runc checkpoint command.
# OPTIONS
- --image-path path to criu image files for restoring
- --work-path path for saving work files and logs
+ --image-path value path to criu image files for restoring
+ --work-path value path for saving work files and logs
--tcp-established allow open tcp connections
--ext-unix-sk allow external unix sockets
--shell-job allow shell jobs
--file-locks handle file locks, for safety
- --manage-cgroups-mode cgroups mode: 'soft' (default), 'full' and 'strict'.
- --bundle, -b path to the root of the bundle directory
+ --manage-cgroups-mode value cgroups mode: 'soft' (default), 'full' and 'strict'
+ --bundle value, -b value path to the root of the bundle directory
--detach, -d detach from the container's process
- --pid-file specify the file to write the process id to
+ --pid-file value specify the file to write the process id to
+ --no-subreaper disable the use of the subreaper used to reap reparented processes
+ --no-pivot do not use pivot root to jail process inside rootfs. This should be used whenever the rootfs is on top of a ramdisk
diff --git a/vendor/github.com/opencontainers/runc/man/runc-resume.8.md b/vendor/github.com/opencontainers/runc/man/runc-resume.8.md
index 627885f1..d864a542 100644
--- a/vendor/github.com/opencontainers/runc/man/runc-resume.8.md
+++ b/vendor/github.com/opencontainers/runc/man/runc-resume.8.md
@@ -2,7 +2,7 @@
runc resume - resumes all processes that have been previously paused
# SYNOPSIS
- runc resume
+ runc resume [container-id...]
Where "" is the name for the instance of the container to be
resumed.
diff --git a/vendor/github.com/opencontainers/runc/man/runc-run.8.md b/vendor/github.com/opencontainers/runc/man/runc-run.8.md
new file mode 100644
index 00000000..b5c6053a
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/man/runc-run.8.md
@@ -0,0 +1,28 @@
+# NAME
+ runc run - create and run a container
+
+# SYNOPSIS
+ runc run [command options]
+
+Where "" is your name for the instance of the container that you
+are starting. The name you provide for the container instance must be unique on
+your host.
+
+# DESCRIPTION
+ The run command creates an instance of a container for a bundle. The bundle
+is a directory with a specification file named "config.json" and a root
+filesystem.
+
+The specification file includes an args parameter. The args parameter is used
+to specify command(s) that get run when the container is started. To change the
+command(s) that get executed on start, edit the args parameter of the spec. See
+"runc spec --help" for more explanation.
+
+# OPTIONS
+ --bundle value, -b value path to the root of the bundle directory, defaults to the current directory
+ --console value specify the pty slave path for use with the container
+ --detach, -d detach from the container's process
+ --pid-file value specify the file to write the process id to
+ --no-subreaper disable the use of the subreaper used to reap reparented processes
+ --no-pivot do not use pivot root to jail process inside rootfs. This should be used whenever the rootfs is on top of a ramdisk
+ --no-new-keyring do not create a new session keyring for the container. This will cause the container to inherit the calling processes session key
diff --git a/vendor/github.com/opencontainers/runc/man/runc-spec.8.md b/vendor/github.com/opencontainers/runc/man/runc-spec.8.md
index 71db7c98..3c69e231 100644
--- a/vendor/github.com/opencontainers/runc/man/runc-spec.8.md
+++ b/vendor/github.com/opencontainers/runc/man/runc-spec.8.md
@@ -14,7 +14,7 @@ parameter that is initially set to call the "sh" command when the container is
started. Calling "sh" may work for an ubuntu container or busybox, but will not
work for containers that do not include the "sh" program.
-EXAMPLE:
+# EXAMPLE
To run docker's hello-world container one needs to set the args parameter
in the spec to call hello. This can be done using the sed command or a text
editor. The following commands create a bundle for hello-world, change the
@@ -35,10 +35,15 @@ In the start command above, "container1" is the name for the instance of the
container that you are starting. The name you provide for the container instance
must be unique on your host.
+An alternative for generating a customized spec config is to use "oci-runtime-tool", the
+sub-command "oci-runtime-tool generate" has lots of options that can be used to do any
+customizations as you want, see [runtime-tools](https://github.com/opencontainers/runtime-tools)
+to get more information.
+
When starting a container through runc, runc needs root privilege. If not
already running as root, you can use sudo to give runc root privilege. For
example: "sudo runc start container1" will give runc root privilege to start the
container on your host.
# OPTIONS
- --bundle, -b path to the root of the bundle directory
+ --bundle value, -b value path to the root of the bundle directory
diff --git a/vendor/github.com/opencontainers/runc/man/runc-start.8.md b/vendor/github.com/opencontainers/runc/man/runc-start.8.md
index ef60f6ca..66721208 100644
--- a/vendor/github.com/opencontainers/runc/man/runc-start.8.md
+++ b/vendor/github.com/opencontainers/runc/man/runc-start.8.md
@@ -1,25 +1,12 @@
# NAME
- runc start - create and run a container
+ runc start - start signals a created container to execute the user defined process
# SYNOPSIS
- runc start [command options]
+ runc start [container-id...]
Where "" is your name for the instance of the container that you
are starting. The name you provide for the container instance must be unique on
your host.
-# DESCRIPTION
- The start command creates an instance of a container for a bundle. The bundle
-is a directory with a specification file named "config.json" and a root
-filesystem.
-
-The specification file includes an args parameter. The args parameter is used
-to specify command(s) that get run when the container is started. To change the
-command(s) that get executed on start, edit the args parameter of the spec. See
-"runc spec --help" for more explanation.
-
-# OPTIONS
- --bundle, -b path to the root of the bundle directory, defaults to the current directory
- --console specify the pty slave path for use with the container
- --detach, -d detach from the container's process
- --pid-file specify the file to write the process id to
+# DESCRIPTIONa
+ The start command signals the container to start the user's defined process.
diff --git a/vendor/github.com/opencontainers/runc/man/runc-update.8.md b/vendor/github.com/opencontainers/runc/man/runc-update.8.md
new file mode 100644
index 00000000..7f9c6465
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/man/runc-update.8.md
@@ -0,0 +1,50 @@
+# NAME
+ runc update - update container resource constraints
+
+# SYNOPSIS
+ runc update [command options]
+
+# DESCRIPTION
+ The data can be read from a file or the standard input, the
+accepted format is as follow (unchanged values can be omitted):
+
+ {
+ "memory": {
+ "limit": 0,
+ "reservation": 0,
+ "swap": 0,
+ "kernel": 0,
+ "kernelTCP": 0
+ },
+ "cpu": {
+ "shares": 0,
+ "quota": 0,
+ "period": 0,
+ "realtimeRuntime": 0,
+ "realtimePeriod": 0,
+ "cpus": "",
+ "mems": ""
+ },
+ "blockIO": {
+ "blkioWeight": 0
+ }
+ }
+
+Note: if data is to be read from a file or the standard input, all
+other options are ignored.
+
+# OPTIONS
+ --resources value, -r value path to the file containing the resources to update or '-' to read from the standard input
+ --blkio-weight value Specifies per cgroup weight, range is from 10 to 1000 (default: 0)
+ --cpu-period value CPU CFS period to be used for hardcapping (in usecs). 0 to use system default
+ --cpu-quota value CPU CFS hardcap limit (in usecs). Allowed cpu time in a given period
+ --cpu-rt-period value CPU realtime period to be used for hardcapping (in usecs). 0 to use system default
+ --cpu-rt-runtime value CPU realtime hardcap limit (in usecs). Allowed cpu time in a given period
+ --cpu-share value CPU shares (relative weight vs. other containers)
+ --cpuset-cpus value CPU(s) to use
+ --cpuset-mems value Memory node(s) to use
+ --kernel-memory value Kernel memory limit (in bytes)
+ --kernel-memory-tcp value Kernel memory limit (in bytes) for tcp buffer
+ --memory value Memory limit (in bytes)
+ --memory-reservation value Memory reservation or soft_limit (in bytes)
+ --memory-swap value Total memory usage (memory + swap); set '-1' to enable unlimited swap
diff --git a/vendor/github.com/opencontainers/runc/man/runc.8.md b/vendor/github.com/opencontainers/runc/man/runc.8.md
index 0ebedfad..b5a8c54f 100644
--- a/vendor/github.com/opencontainers/runc/man/runc.8.md
+++ b/vendor/github.com/opencontainers/runc/man/runc.8.md
@@ -6,7 +6,7 @@
# DESCRIPTION
runc is a command line client for running applications packaged according to
-the Open Container Format (OCF) and is a compliant implementation of the
+the Open Container Initiative (OCI) format and is a compliant implementation of the
Open Container Initiative specification.
runc integrates well with existing process supervisors to provide a production
@@ -32,22 +32,26 @@ value for "bundle" is the current directory.
delete delete any resources held by the container often used with detached containers
events display container events such as OOM notifications, cpu, memory, IO and network stats
exec execute new process inside the container
+ init initialize the namespaces and launch the process (do not call it outside of runc)
kill kill sends the specified signal (default: SIGTERM) to the container's init process
list lists containers started by runc with the given root
pause pause suspends all processes inside the container
+ ps displays the processes running inside a container
restore restore a container from a previous checkpoint
resume resumes all processes that have been previously paused
+ run create and run a container
spec create a new specification file
- start create and run a container
+ start executes the user defined process in a created container
state output the state of a container
+ update update container resource constraints
help, h Shows a list of commands or help for one command
# GLOBAL OPTIONS
- --debug enable debug output for logging
- --log set the log file path where internal debug information is written
- --log-format "text" set the format used by logs ('text' (default), or 'json')
- --root "/run/opencontainer/containers" root directory for storage of container state (this should be located in tmpfs)
- --criu "criu" path to the criu binary used for checkpoint and restore
- --systemd-cgroup enable systemd cgroup support, expects cgroupsPath to be of form "slice:prefix:name" for e.g. "system.slice:runc:434234"
- --help, -h show help
- --version, -v print the version
+ --debug enable debug output for logging
+ --log value set the log file path where internal debug information is written (default: "/dev/null")
+ --log-format value set the format used by logs ('text' (default), or 'json') (default: "text")
+ --root value root directory for storage of container state (this should be located in tmpfs) (default: "/run/runc")
+ --criu value path to the criu binary used for checkpoint and restore (default: "criu")
+ --systemd-cgroup enable systemd cgroup support, expects cgroupsPath to be of form "slice:prefix:name" for e.g. "system.slice:runc:434234"
+ --help, -h show help
+ --version, -v print the version
diff --git a/vendor/github.com/opencontainers/runc/pause.go b/vendor/github.com/opencontainers/runc/pause.go
index ccec7bbe..f08cf4f2 100644
--- a/vendor/github.com/opencontainers/runc/pause.go
+++ b/vendor/github.com/opencontainers/runc/pause.go
@@ -2,46 +2,89 @@
package main
-import "github.com/codegangsta/cli"
+import (
+ "fmt"
+ "os"
+
+ "github.com/urfave/cli"
+)
var pauseCommand = cli.Command{
Name: "pause",
Usage: "pause suspends all processes inside the container",
- ArgsUsage: `
+ ArgsUsage: ` [container-id...]
Where "" is the name for the instance of the container to be
paused. `,
Description: `The pause command suspends all processes in the instance of the container.
Use runc list to identiy instances of containers and their current status.`,
- Action: func(context *cli.Context) {
- container, err := getContainer(context)
+ Action: func(context *cli.Context) error {
+ if err := checkArgs(context, 1, minArgs); err != nil {
+ return err
+ }
+ hasError := false
+ factory, err := loadFactory(context)
if err != nil {
- fatal(err)
+ return err
}
- if err := container.Pause(); err != nil {
- fatal(err)
+
+ for _, id := range context.Args() {
+ container, err := factory.Load(id)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "container %s does not exist\n", id)
+ hasError = true
+ continue
+ }
+ if err := container.Pause(); err != nil {
+ fmt.Fprintf(os.Stderr, "pause container %s : %s\n", id, err)
+ hasError = true
+ }
}
+
+ if hasError {
+ return fmt.Errorf("one or more of container pause failed")
+ }
+ return nil
},
}
var resumeCommand = cli.Command{
Name: "resume",
Usage: "resumes all processes that have been previously paused",
- ArgsUsage: `
+ ArgsUsage: ` [container-id...]
Where "" is the name for the instance of the container to be
resumed.`,
Description: `The resume command resumes all processes in the instance of the container.
Use runc list to identiy instances of containers and their current status.`,
- Action: func(context *cli.Context) {
- container, err := getContainer(context)
+ Action: func(context *cli.Context) error {
+ if err := checkArgs(context, 1, minArgs); err != nil {
+ return err
+ }
+ hasError := false
+ factory, err := loadFactory(context)
if err != nil {
- fatal(err)
+ return err
}
- if err := container.Resume(); err != nil {
- fatal(err)
+
+ for _, id := range context.Args() {
+ container, err := factory.Load(id)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "container %s does not exist\n", id)
+ hasError = true
+ continue
+ }
+ if err := container.Resume(); err != nil {
+ fmt.Fprintf(os.Stderr, "resume container %s : %s\n", id, err)
+ hasError = true
+ }
}
+
+ if hasError {
+ return fmt.Errorf("one or more of container resume failed")
+ }
+ return nil
},
}
diff --git a/vendor/github.com/opencontainers/runc/ps.go b/vendor/github.com/opencontainers/runc/ps.go
new file mode 100644
index 00000000..228f161a
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/ps.go
@@ -0,0 +1,100 @@
+// +build linux
+
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+ "os/exec"
+ "strconv"
+ "strings"
+
+ "github.com/urfave/cli"
+)
+
+var psCommand = cli.Command{
+ Name: "ps",
+ Usage: "ps displays the processes running inside a container",
+ ArgsUsage: ` [ps options]`,
+ Flags: []cli.Flag{
+ cli.StringFlag{
+ Name: "format, f",
+ Value: "",
+ Usage: `select one of: ` + formatOptions,
+ },
+ },
+ Action: func(context *cli.Context) error {
+ if err := checkArgs(context, 1, minArgs); err != nil {
+ return err
+ }
+ container, err := getContainer(context)
+ if err != nil {
+ return err
+ }
+
+ pids, err := container.Processes()
+ if err != nil {
+ return err
+ }
+
+ if context.String("format") == "json" {
+ return json.NewEncoder(os.Stdout).Encode(pids)
+ }
+
+ // [1:] is to remove command name, ex:
+ // context.Args(): [containet_id ps_arg1 ps_arg2 ...]
+ // psArgs: [ps_arg1 ps_arg2 ...]
+ //
+ psArgs := context.Args()[1:]
+ if len(psArgs) == 0 {
+ psArgs = []string{"-ef"}
+ }
+
+ cmd := exec.Command("ps", psArgs...)
+ output, err := cmd.CombinedOutput()
+ if err != nil {
+ return fmt.Errorf("%s: %s", err, output)
+ }
+
+ lines := strings.Split(string(output), "\n")
+ pidIndex, err := getPidIndex(lines[0])
+ if err != nil {
+ return err
+ }
+
+ fmt.Println(lines[0])
+ for _, line := range lines[1:] {
+ if len(line) == 0 {
+ continue
+ }
+ fields := strings.Fields(line)
+ p, err := strconv.Atoi(fields[pidIndex])
+ if err != nil {
+ return fmt.Errorf("unexpected pid '%s': %s", fields[pidIndex], err)
+ }
+
+ for _, pid := range pids {
+ if pid == p {
+ fmt.Println(line)
+ break
+ }
+ }
+ }
+ return nil
+ },
+ SkipArgReorder: true,
+}
+
+func getPidIndex(title string) (int, error) {
+ titles := strings.Fields(title)
+
+ pidIndex := -1
+ for i, name := range titles {
+ if name == "PID" {
+ return i, nil
+ }
+ }
+
+ return pidIndex, fmt.Errorf("couldn't find PID field in ps output")
+}
diff --git a/vendor/github.com/opencontainers/runc/restore.go b/vendor/github.com/opencontainers/runc/restore.go
index 13f3b6d2..91b1efe5 100644
--- a/vendor/github.com/opencontainers/runc/restore.go
+++ b/vendor/github.com/opencontainers/runc/restore.go
@@ -7,11 +7,11 @@ import (
"syscall"
"github.com/Sirupsen/logrus"
- "github.com/codegangsta/cli"
"github.com/opencontainers/runc/libcontainer"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/specconv"
"github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/urfave/cli"
)
var restoreCommand = cli.Command{
@@ -53,7 +53,7 @@ using the runc checkpoint command.`,
cli.StringFlag{
Name: "manage-cgroups-mode",
Value: "",
- Usage: "cgroups mode: 'soft' (default), 'full' and 'strict'.",
+ Usage: "cgroups mode: 'soft' (default), 'full' and 'strict'",
},
cli.StringFlag{
Name: "bundle, b",
@@ -77,12 +77,19 @@ using the runc checkpoint command.`,
Name: "no-pivot",
Usage: "do not use pivot root to jail process inside rootfs. This should be used whenever the rootfs is on top of a ramdisk",
},
+ cli.StringSliceFlag{
+ Name: "empty-ns",
+ Usage: "create a namespace, but don't restore its properies",
+ },
},
- Action: func(context *cli.Context) {
+ Action: func(context *cli.Context) error {
+ if err := checkArgs(context, 1, exactArgs); err != nil {
+ return err
+ }
imagePath := context.String("image-path")
id := context.Args().First()
if id == "" {
- fatal(errEmptyID)
+ return errEmptyID
}
if imagePath == "" {
imagePath = getDefaultImagePath(context)
@@ -90,12 +97,12 @@ using the runc checkpoint command.`,
bundle := context.String("bundle")
if bundle != "" {
if err := os.Chdir(bundle); err != nil {
- fatal(err)
+ return err
}
}
spec, err := loadSpec(specConfig)
if err != nil {
- fatal(err)
+ return err
}
config, err := specconv.CreateLibcontainerConfig(&specconv.CreateOpts{
CgroupName: id,
@@ -104,19 +111,20 @@ using the runc checkpoint command.`,
Spec: spec,
})
if err != nil {
- fatal(err)
+ return err
}
status, err := restoreContainer(context, spec, config, imagePath)
- if err != nil {
- fatal(err)
+ if err == nil {
+ os.Exit(status)
}
- os.Exit(status)
+ return err
},
}
-func restoreContainer(context *cli.Context, spec *specs.Spec, config *configs.Config, imagePath string) (code int, err error) {
+func restoreContainer(context *cli.Context, spec *specs.Spec, config *configs.Config, imagePath string) (int, error) {
var (
rootuid = 0
+ rootgid = 0
id = context.Args().First()
)
factory, err := loadFactory(context)
@@ -142,6 +150,10 @@ func restoreContainer(context *cli.Context, spec *specs.Spec, config *configs.Co
setManageCgroupsMode(context, options)
+ if err = setEmptyNsMask(context, options); err != nil {
+ return -1, err
+ }
+
// ensure that the container is always removed if we were the process
// that created it.
detach := context.Bool("detach")
@@ -149,29 +161,30 @@ func restoreContainer(context *cli.Context, spec *specs.Spec, config *configs.Co
defer destroy(container)
}
process := &libcontainer.Process{}
- tty, err := setupIO(process, rootuid, "", false, detach)
+ tty, err := setupIO(process, rootuid, rootgid, false, detach)
if err != nil {
return -1, err
}
- defer tty.Close()
- handler := newSignalHandler(tty, !context.Bool("no-subreaper"))
+ handler := newSignalHandler(!context.Bool("no-subreaper"))
if err := container.Restore(process, options); err != nil {
return -1, err
}
+ // We don't need to do a tty.recvtty because config.Terminal is always false.
+ defer tty.Close()
if err := tty.ClosePostStart(); err != nil {
return -1, err
}
if pidFile := context.String("pid-file"); pidFile != "" {
if err := createPidFile(pidFile, process); err != nil {
- process.Signal(syscall.SIGKILL)
- process.Wait()
+ _ = process.Signal(syscall.SIGKILL)
+ _, _ = process.Wait()
return -1, err
}
}
if detach {
return 0, nil
}
- return handler.forward(process)
+ return handler.forward(process, tty)
}
func criuOptions(context *cli.Context) *libcontainer.CriuOpts {
diff --git a/vendor/github.com/opencontainers/runc/rlimit_linux.go b/vendor/github.com/opencontainers/runc/rlimit_linux.go
index 0de8b0b2..c97a0fb4 100644
--- a/vendor/github.com/opencontainers/runc/rlimit_linux.go
+++ b/vendor/github.com/opencontainers/runc/rlimit_linux.go
@@ -43,7 +43,7 @@ var rlimitMap = map[string]int{
func strToRlimit(key string) (int, error) {
rl, ok := rlimitMap[key]
if !ok {
- return 0, fmt.Errorf("Wrong rlimit value: %s", key)
+ return 0, fmt.Errorf("wrong rlimit value: %s", key)
}
return rl, nil
}
diff --git a/vendor/github.com/opencontainers/runc/run.go b/vendor/github.com/opencontainers/runc/run.go
new file mode 100644
index 00000000..6a0a6229
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/run.go
@@ -0,0 +1,80 @@
+// +build linux
+
+package main
+
+import (
+ "os"
+
+ "github.com/urfave/cli"
+)
+
+// default action is to start a container
+var runCommand = cli.Command{
+ Name: "run",
+ Usage: "create and run a container",
+ ArgsUsage: `
+
+Where "" is your name for the instance of the container that you
+are starting. The name you provide for the container instance must be unique on
+your host.`,
+ Description: `The run command creates an instance of a container for a bundle. The bundle
+is a directory with a specification file named "` + specConfig + `" and a root
+filesystem.
+
+The specification file includes an args parameter. The args parameter is used
+to specify command(s) that get run when the container is started. To change the
+command(s) that get executed on start, edit the args parameter of the spec. See
+"runc spec --help" for more explanation.`,
+ Flags: []cli.Flag{
+ cli.StringFlag{
+ Name: "bundle, b",
+ Value: "",
+ Usage: `path to the root of the bundle directory, defaults to the current directory`,
+ },
+ cli.StringFlag{
+ Name: "console-socket",
+ Value: "",
+ Usage: "path to an AF_UNIX socket which will receive a file descriptor referencing the master end of the console's pseudoterminal",
+ },
+ cli.BoolFlag{
+ Name: "detach, d",
+ Usage: "detach from the container's process",
+ },
+ cli.StringFlag{
+ Name: "pid-file",
+ Value: "",
+ Usage: "specify the file to write the process id to",
+ },
+ cli.BoolFlag{
+ Name: "no-subreaper",
+ Usage: "disable the use of the subreaper used to reap reparented processes",
+ },
+ cli.BoolFlag{
+ Name: "no-pivot",
+ Usage: "do not use pivot root to jail process inside rootfs. This should be used whenever the rootfs is on top of a ramdisk",
+ },
+ cli.BoolFlag{
+ Name: "no-new-keyring",
+ Usage: "do not create a new session keyring for the container. This will cause the container to inherit the calling processes session key",
+ },
+ },
+ Action: func(context *cli.Context) error {
+ if err := checkArgs(context, 1, exactArgs); err != nil {
+ return err
+ }
+ if err := revisePidFile(context); err != nil {
+ return err
+ }
+ spec, err := setupSpec(context)
+ if err != nil {
+ return err
+ }
+ status, err := startContainer(context, spec, false)
+ if err == nil {
+ // exit with the container's exit status so any external supervisor is
+ // notified of the exit with the correct exit status.
+ os.Exit(status)
+ }
+ return err
+ },
+}
diff --git a/vendor/github.com/opencontainers/runc/script/check-config.sh b/vendor/github.com/opencontainers/runc/script/check-config.sh
new file mode 100755
index 00000000..0fd9ab19
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/script/check-config.sh
@@ -0,0 +1,247 @@
+#!/usr/bin/env bash
+set -e
+
+# bits of this were adapted from check_config.sh in docker
+# see also https://github.com/docker/docker/blob/master/contrib/check-config.sh
+
+possibleConfigs=(
+ '/proc/config.gz'
+ "/boot/config-$(uname -r)"
+ "/usr/src/linux-$(uname -r)/.config"
+ '/usr/src/linux/.config'
+)
+possibleConfigFiles=(
+ 'config.gz'
+ "config-$(uname -r)"
+ '.config'
+)
+
+if ! command -v zgrep &>/dev/null; then
+ zgrep() {
+ zcat "$2" | grep "$1"
+ }
+fi
+
+kernelVersion="$(uname -r)"
+kernelMajor="${kernelVersion%%.*}"
+kernelMinor="${kernelVersion#$kernelMajor.}"
+kernelMinor="${kernelMinor%%.*}"
+
+is_set() {
+ zgrep "CONFIG_$1=[y|m]" "$CONFIG" >/dev/null
+}
+is_set_in_kernel() {
+ zgrep "CONFIG_$1=y" "$CONFIG" >/dev/null
+}
+is_set_as_module() {
+ zgrep "CONFIG_$1=m" "$CONFIG" >/dev/null
+}
+
+color() {
+ local codes=()
+ if [ "$1" = 'bold' ]; then
+ codes=("${codes[@]}" '1')
+ shift
+ fi
+ if [ "$#" -gt 0 ]; then
+ local code=
+ case "$1" in
+ # see https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
+ black) code=30 ;;
+ red) code=31 ;;
+ green) code=32 ;;
+ yellow) code=33 ;;
+ blue) code=34 ;;
+ magenta) code=35 ;;
+ cyan) code=36 ;;
+ white) code=37 ;;
+ esac
+ if [ "$code" ]; then
+ codes=("${codes[@]}" "$code")
+ fi
+ fi
+ local IFS=';'
+ echo -en '\033['"${codes[*]}"'m'
+}
+wrap_color() {
+ text="$1"
+ shift
+ color "$@"
+ echo -n "$text"
+ color reset
+ echo
+}
+
+wrap_good() {
+ echo "$(wrap_color "$1" white): $(wrap_color "$2" green)"
+}
+wrap_bad() {
+ echo "$(wrap_color "$1" bold): $(wrap_color "$2" bold red)"
+}
+wrap_warning() {
+ wrap_color >&2 "$*" red
+}
+
+check_flag() {
+ if is_set_in_kernel "$1"; then
+ wrap_good "CONFIG_$1" 'enabled'
+ elif is_set_as_module "$1"; then
+ wrap_good "CONFIG_$1" 'enabled (as module)'
+ else
+ wrap_bad "CONFIG_$1" 'missing'
+ fi
+}
+
+check_flags() {
+ for flag in "$@"; do
+ echo "- $(check_flag "$flag")"
+ done
+}
+
+check_distro_userns() {
+ source /etc/os-release 2>/dev/null || /bin/true
+ if [[ "${ID}" =~ ^(centos|rhel)$ && "${VERSION_ID}" =~ ^7 ]]; then
+ # this is a CentOS7 or RHEL7 system
+ grep -q "user_namespace.enable=1" /proc/cmdline || {
+ # no user namespace support enabled
+ wrap_bad " (RHEL7/CentOS7" "User namespaces disabled; add 'user_namespace.enable=1' to boot command line)"
+ }
+ fi
+}
+
+is_config() {
+ local config="$1"
+
+ # Todo: more check
+ [[ -f "$config" ]] && return 0
+ return 1
+}
+
+search_config() {
+ local target_dir="$1"
+ [[ "$target_dir" ]] || target_dir=("${possibleConfigs[@]}")
+
+ local tryConfig
+ for tryConfig in "${target_dir[@]}"; do
+ is_config "$tryConfig" && {
+ CONFIG="$tryConfig"
+ return
+ }
+ [[ -d "$tryConfig" ]] && {
+ for tryFile in "${possibleConfigFiles[@]}"; do
+ is_config "$tryConfig/$tryFile" && {
+ CONFIG="$tryConfig/$tryFile"
+ return
+ }
+ done
+ }
+ done
+
+ wrap_warning "error: cannot find kernel config"
+ wrap_warning " try running this script again, specifying the kernel config:"
+ wrap_warning " CONFIG=/path/to/kernel/.config $0 or $0 /path/to/kernel/.config"
+ exit 1
+}
+
+CONFIG="$1"
+
+is_config "$CONFIG" || {
+ if [[ ! "$CONFIG" ]]; then
+ wrap_color "info: no config specified, searching for kernel config ..." white
+ search_config
+ elif [[ -d "$CONFIG" ]]; then
+ wrap_color "info: input is a directory, searching for kernel config in this directory..." white
+ search_config "$CONFIG"
+ else
+ wrap_warning "warning: $CONFIG seems not a kernel config, searching other paths for kernel config ..."
+ search_config
+ fi
+}
+
+wrap_color "info: reading kernel config from $CONFIG ..." white
+echo
+
+echo 'Generally Necessary:'
+
+echo -n '- '
+cgroupSubsystemDir="$(awk '/[, ](cpu|cpuacct|cpuset|devices|freezer|memory)[, ]/ && $3 == "cgroup" { print $2 }' /proc/mounts | head -n1)"
+cgroupDir="$(dirname "$cgroupSubsystemDir")"
+if [ -d "$cgroupDir/cpu" -o -d "$cgroupDir/cpuacct" -o -d "$cgroupDir/cpuset" -o -d "$cgroupDir/devices" -o -d "$cgroupDir/freezer" -o -d "$cgroupDir/memory" ]; then
+ echo "$(wrap_good 'cgroup hierarchy' 'properly mounted') [$cgroupDir]"
+else
+ if [ "$cgroupSubsystemDir" ]; then
+ echo "$(wrap_bad 'cgroup hierarchy' 'single mountpoint!') [$cgroupSubsystemDir]"
+ else
+ echo "$(wrap_bad 'cgroup hierarchy' 'nonexistent??')"
+ fi
+ echo " $(wrap_color '(see https://github.com/tianon/cgroupfs-mount)' yellow)"
+fi
+
+if [ "$(cat /sys/module/apparmor/parameters/enabled 2>/dev/null)" = 'Y' ]; then
+ echo -n '- '
+ if command -v apparmor_parser &>/dev/null; then
+ echo "$(wrap_good 'apparmor' 'enabled and tools installed')"
+ else
+ echo "$(wrap_bad 'apparmor' 'enabled, but apparmor_parser missing')"
+ echo -n ' '
+ if command -v apt-get &>/dev/null; then
+ echo "$(wrap_color '(use "apt-get install apparmor" to fix this)')"
+ elif command -v yum &>/dev/null; then
+ echo "$(wrap_color '(your best bet is "yum install apparmor-parser")')"
+ else
+ echo "$(wrap_color '(look for an "apparmor" package for your distribution)')"
+ fi
+ fi
+fi
+
+flags=(
+ NAMESPACES {NET,PID,IPC,UTS}_NS
+ CGROUPS CGROUP_CPUACCT CGROUP_DEVICE CGROUP_FREEZER CGROUP_SCHED CPUSETS MEMCG
+ KEYS
+ MACVLAN VETH BRIDGE BRIDGE_NETFILTER
+ NF_NAT_IPV4 IP_NF_FILTER IP_NF_TARGET_MASQUERADE
+ NETFILTER_XT_MATCH_{ADDRTYPE,CONNTRACK}
+ NF_NAT NF_NAT_NEEDED
+
+ # required for bind-mounting /dev/mqueue into containers
+ POSIX_MQUEUE
+)
+check_flags "${flags[@]}"
+echo
+
+echo 'Optional Features:'
+{
+ check_flags USER_NS
+ check_distro_userns
+
+ check_flags SECCOMP
+ check_flags CGROUP_PIDS
+
+ check_flags MEMCG_SWAP MEMCG_SWAP_ENABLED
+ if is_set MEMCG_SWAP && ! is_set MEMCG_SWAP_ENABLED; then
+ echo " $(wrap_color '(note that cgroup swap accounting is not enabled in your kernel config, you can enable it by setting boot option "swapaccount=1")' bold black)"
+ fi
+}
+
+if [ "$kernelMajor" -lt 4 ] || [ "$kernelMajor" -eq 4 -a "$kernelMinor" -le 5 ]; then
+ check_flags MEMCG_KMEM
+fi
+
+if [ "$kernelMajor" -lt 3 ] || [ "$kernelMajor" -eq 3 -a "$kernelMinor" -le 18 ]; then
+ check_flags RESOURCE_COUNTERS
+fi
+
+if [ "$kernelMajor" -lt 3 ] || [ "$kernelMajor" -eq 3 -a "$kernelMinor" -le 13 ]; then
+ netprio=NETPRIO_CGROUP
+else
+ netprio=CGROUP_NET_PRIO
+fi
+
+flags=(
+ BLK_CGROUP BLK_DEV_THROTTLING IOSCHED_CFQ CFQ_GROUP_IOSCHED
+ CGROUP_PERF
+ CGROUP_HUGETLB
+ NET_CLS_CGROUP $netprio
+ CFS_BANDWIDTH FAIR_GROUP_SCHED RT_GROUP_SCHED
+)
+check_flags "${flags[@]}"
diff --git a/vendor/github.com/opencontainers/runc/script/test_Dockerfile b/vendor/github.com/opencontainers/runc/script/test_Dockerfile
deleted file mode 100644
index 2fe73586..00000000
--- a/vendor/github.com/opencontainers/runc/script/test_Dockerfile
+++ /dev/null
@@ -1,32 +0,0 @@
-FROM golang:1.5.3
-
-RUN echo "deb http://ftp.us.debian.org/debian testing main contrib" >> /etc/apt/sources.list
-RUN apt-get update && apt-get install -y \
- build-essential \
- curl \
- iptables \
- libaio-dev \
- libcap-dev \
- libprotobuf-dev \
- libprotobuf-c0-dev \
- libseccomp2 \
- libseccomp-dev \
- protobuf-c-compiler \
- protobuf-compiler \
- python-minimal \
- --no-install-recommends
-
-# install criu
-ENV CRIU_VERSION 1.7
-RUN mkdir -p /usr/src/criu \
- && curl -sSL https://github.com/xemul/criu/archive/v${CRIU_VERSION}.tar.gz | tar -v -C /usr/src/criu/ -xz --strip-components=1 \
- && cd /usr/src/criu \
- && make install-criu
-
-# setup a playground for us to spawn containers in
-RUN mkdir /busybox && \
- curl -sSL 'https://github.com/jpetazzo/docker-busybox/raw/buildroot-2014.11/rootfs.tar' | tar -xC /busybox
-
-COPY script/tmpmount /
-WORKDIR /go/src/github.com/opencontainers/runc
-ENTRYPOINT ["/tmpmount"]
diff --git a/vendor/github.com/opencontainers/runc/script/validate-gofmt b/vendor/github.com/opencontainers/runc/script/validate-gofmt
index c565976b..0810765f 100755
--- a/vendor/github.com/opencontainers/runc/script/validate-gofmt
+++ b/vendor/github.com/opencontainers/runc/script/validate-gofmt
@@ -3,14 +3,14 @@
source "$(dirname "$BASH_SOURCE")/.validate"
IFS=$'\n'
-files=( $(validate_diff --diff-filter=ACMR --name-only -- '*.go' | grep -v '^Godeps/' || true) )
+files=($(validate_diff --diff-filter=ACMR --name-only -- '*.go' | grep -v '^Godeps/' || true))
unset IFS
badFiles=()
for f in "${files[@]}"; do
# we use "git show" here to validate that what's committed is formatted
if [ "$(git show "$VALIDATE_HEAD:$f" | gofmt -s -l)" ]; then
- badFiles+=( "$f" )
+ badFiles+=("$f")
fi
done
diff --git a/vendor/github.com/opencontainers/runc/script/validate-shfmt b/vendor/github.com/opencontainers/runc/script/validate-shfmt
new file mode 100755
index 00000000..84930399
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/script/validate-shfmt
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+badFiles=()
+while read f; do
+ badFiles+=("$f")
+done < <(shfmt -l . | grep -v Godeps/)
+
+if [ ${#badFiles[@]} -eq 0 ]; then
+ echo 'Congratulations! All shell source files are properly formatted.'
+else
+ {
+ echo "These files are not properly shfmt'd:"
+ for f in "${badFiles[@]}"; do
+ echo " - $f"
+ done
+ echo
+ echo 'Please reformat the above files using "shfmt -w" and commit the result.'
+ echo
+ } >&2
+ false
+fi
diff --git a/vendor/github.com/opencontainers/runc/signals.go b/vendor/github.com/opencontainers/runc/signals.go
index 5eee44e7..f3dcf179 100644
--- a/vendor/github.com/opencontainers/runc/signals.go
+++ b/vendor/github.com/opencontainers/runc/signals.go
@@ -17,7 +17,7 @@ const signalBufferSize = 2048
// newSignalHandler returns a signal handler for processing SIGCHLD and SIGWINCH signals
// while still forwarding all other signals to the process.
-func newSignalHandler(tty *tty, enableSubreaper bool) *signalHandler {
+func newSignalHandler(enableSubreaper bool) *signalHandler {
if enableSubreaper {
// set us as the subreaper before registering the signal handler for the container
if err := system.SetSubreaper(1); err != nil {
@@ -30,7 +30,6 @@ func newSignalHandler(tty *tty, enableSubreaper bool) *signalHandler {
// handle all signals for the process.
signal.Notify(s)
return &signalHandler{
- tty: tty,
signals: s,
}
}
@@ -44,12 +43,11 @@ type exit struct {
type signalHandler struct {
signals chan os.Signal
- tty *tty
}
// forward handles the main signal event loop forwarding, resizing, or reaping depending
// on the signal received.
-func (h *signalHandler) forward(process *libcontainer.Process) (int, error) {
+func (h *signalHandler) forward(process *libcontainer.Process, tty *tty) (int, error) {
// make sure we know the pid of our main process so that we can return
// after it dies.
pid1, err := process.Pid()
@@ -57,11 +55,11 @@ func (h *signalHandler) forward(process *libcontainer.Process) (int, error) {
return -1, err
}
// perform the initial tty resize.
- h.tty.resize()
+ tty.resize()
for s := range h.signals {
switch s {
case syscall.SIGWINCH:
- h.tty.resize()
+ tty.resize()
case syscall.SIGCHLD:
exits, err := h.reap()
if err != nil {
diff --git a/vendor/github.com/opencontainers/runc/spec.go b/vendor/github.com/opencontainers/runc/spec.go
index 69ea1e50..4a89a40a 100644
--- a/vendor/github.com/opencontainers/runc/spec.go
+++ b/vendor/github.com/opencontainers/runc/spec.go
@@ -9,9 +9,9 @@ import (
"os"
"runtime"
- "github.com/codegangsta/cli"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/urfave/cli"
)
var specCommand = cli.Command{
@@ -42,12 +42,17 @@ command in a new hello-world container named container1:
tar -C rootfs -xf hello-world.tar
runc spec
sed -i 's;"sh";"/hello";' ` + specConfig + `
- runc start container1
+ runc run container1
-In the start command above, "container1" is the name for the instance of the
+In the run command above, "container1" is the name for the instance of the
container that you are starting. The name you provide for the container instance
must be unique on your host.
+An alternative for generating a customized spec config is to use "oci-runtime-tool", the
+sub-command "oci-runtime-tool generate" has lots of options that can be used to do any
+customizations as you want, see [runtime-tools](https://github.com/opencontainers/runtime-tools)
+to get more information.
+
When starting a container through runc, runc needs root privilege. If not
already running as root, you can use sudo to give runc root privilege. For
example: "sudo runc start container1" will give runc root privilege to start the
@@ -59,7 +64,10 @@ container on your host.`,
Usage: "path to the root of the bundle directory",
},
},
- Action: func(context *cli.Context) {
+ Action: func(context *cli.Context) error {
+ if err := checkArgs(context, 0, exactArgs); err != nil {
+ return err
+ }
spec := specs.Spec{
Version: specs.Version,
Platform: specs.Platform{
@@ -87,7 +95,7 @@ container on your host.`,
"CAP_KILL",
"CAP_NET_BIND_SERVICE",
},
- Rlimits: []specs.Rlimit{
+ Rlimits: []specs.LinuxRlimit{
{
Type: "RLIMIT_NOFILE",
Hard: uint64(1024),
@@ -140,12 +148,14 @@ container on your host.`,
Options: []string{"nosuid", "noexec", "nodev", "relatime", "ro"},
},
},
- Linux: specs.Linux{
+ Linux: &specs.Linux{
MaskedPaths: []string{
"/proc/kcore",
"/proc/latency_stats",
+ "/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
+ "/sys/firmware",
},
ReadonlyPaths: []string{
"/proc/asound",
@@ -155,15 +165,15 @@ container on your host.`,
"/proc/sys",
"/proc/sysrq-trigger",
},
- Resources: &specs.Resources{
- Devices: []specs.DeviceCgroup{
+ Resources: &specs.LinuxResources{
+ Devices: []specs.LinuxDeviceCgroup{
{
Allow: false,
Access: sPtr("rwm"),
},
},
},
- Namespaces: []specs.Namespace{
+ Namespaces: []specs.LinuxNamespace{
{
Type: "pid",
},
@@ -196,30 +206,26 @@ container on your host.`,
bundle := context.String("bundle")
if bundle != "" {
if err := os.Chdir(bundle); err != nil {
- fatal(err)
+ return err
}
}
if err := checkNoFile(specConfig); err != nil {
- fatal(err)
+ return err
}
data, err := json.MarshalIndent(&spec, "", "\t")
if err != nil {
- fatal(err)
+ return err
}
if err := ioutil.WriteFile(specConfig, data, 0666); err != nil {
- fatal(err)
+ return err
}
+ return nil
},
}
-func sPtr(s string) *string { return &s }
-func rPtr(r rune) *rune { return &r }
-func iPtr(i int64) *int64 { return &i }
-func u32Ptr(i int64) *uint32 { u := uint32(i); return &u }
-func fmPtr(i int64) *os.FileMode { fm := os.FileMode(i); return &fm }
+func sPtr(s string) *string { return &s }
// loadSpec loads the specification from the provided path.
-// If the path is empty then the default path will be "config.json"
func loadSpec(cPath string) (spec *specs.Spec, err error) {
cf, err := os.Open(cPath)
if err != nil {
@@ -233,17 +239,30 @@ func loadSpec(cPath string) (spec *specs.Spec, err error) {
if err = json.NewDecoder(cf).Decode(&spec); err != nil {
return nil, err
}
+ if err = validatePlatform(&spec.Platform); err != nil {
+ return nil, err
+ }
return spec, validateProcessSpec(&spec.Process)
}
-func createLibContainerRlimit(rlimit specs.Rlimit) (configs.Rlimit, error) {
+func createLibContainerRlimit(rlimit specs.LinuxRlimit) (configs.Rlimit, error) {
rl, err := strToRlimit(rlimit.Type)
if err != nil {
return configs.Rlimit{}, err
}
return configs.Rlimit{
Type: rl,
- Hard: uint64(rlimit.Hard),
- Soft: uint64(rlimit.Soft),
+ Hard: rlimit.Hard,
+ Soft: rlimit.Soft,
}, nil
}
+
+func validatePlatform(platform *specs.Platform) error {
+ if platform.OS != runtime.GOOS {
+ return fmt.Errorf("target os %s mismatch with current os %s", platform.OS, runtime.GOOS)
+ }
+ if platform.Arch != runtime.GOARCH {
+ return fmt.Errorf("target arch %s mismatch with current arch %s", platform.Arch, runtime.GOARCH)
+ }
+ return nil
+}
diff --git a/vendor/github.com/opencontainers/runc/start.go b/vendor/github.com/opencontainers/runc/start.go
index dcdcb324..9dd9dfd6 100644
--- a/vendor/github.com/opencontainers/runc/start.go
+++ b/vendor/github.com/opencontainers/runc/start.go
@@ -1,138 +1,66 @@
-// +build linux
-
package main
import (
+ "fmt"
"os"
- "runtime"
- "github.com/codegangsta/cli"
- "github.com/coreos/go-systemd/activation"
"github.com/opencontainers/runc/libcontainer"
- "github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/urfave/cli"
)
-// default action is to start a container
var startCommand = cli.Command{
Name: "start",
- Usage: "create and run a container",
- ArgsUsage: `
+ Usage: "executes the user defined process in a created container",
+ ArgsUsage: ` [container-id...]
Where "" is your name for the instance of the container that you
are starting. The name you provide for the container instance must be unique on
your host.`,
- Description: `The start command creates an instance of a container for a bundle. The bundle
-is a directory with a specification file named "` + specConfig + `" and a root
-filesystem.
+ Description: `The start command executes the user defined process in a created container .`,
+ Action: func(context *cli.Context) error {
+ if err := checkArgs(context, 1, minArgs); err != nil {
+ return err
+ }
+ hasError := false
+ factory, err := loadFactory(context)
+ if err != nil {
+ return err
+ }
-The specification file includes an args parameter. The args parameter is used
-to specify command(s) that get run when the container is started. To change the
-command(s) that get executed on start, edit the args parameter of the spec. See
-"runc spec --help" for more explanation.`,
- Flags: []cli.Flag{
- cli.StringFlag{
- Name: "bundle, b",
- Value: "",
- Usage: `path to the root of the bundle directory, defaults to the current directory`,
- },
- cli.StringFlag{
- Name: "console",
- Value: "",
- Usage: "specify the pty slave path for use with the container",
- },
- cli.BoolFlag{
- Name: "detach,d",
- Usage: "detach from the container's process",
- },
- cli.StringFlag{
- Name: "pid-file",
- Value: "",
- Usage: "specify the file to write the process id to",
- },
- cli.BoolFlag{
- Name: "no-subreaper",
- Usage: "disable the use of the subreaper used to reap reparented processes",
- },
- cli.BoolFlag{
- Name: "no-pivot",
- Usage: "do not use pivot root to jail process inside rootfs. This should be used whenever the rootfs is on top of a ramdisk",
- },
- },
- Action: func(context *cli.Context) {
- bundle := context.String("bundle")
- if bundle != "" {
- if err := os.Chdir(bundle); err != nil {
- fatal(err)
+ for _, id := range context.Args() {
+ container, err := factory.Load(id)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "container %s does not exist\n", id)
+ hasError = true
+ continue
+ }
+ status, err := container.Status()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "status for %s: %v\n", id, err)
+ hasError = true
+ continue
+ }
+ switch status {
+ case libcontainer.Created:
+ if err := container.Exec(); err != nil {
+ fmt.Fprintf(os.Stderr, "start for %s failed: %v\n", id, err)
+ hasError = true
+ }
+ case libcontainer.Stopped:
+ fmt.Fprintln(os.Stderr, "cannot start a container that has run and stopped")
+ hasError = true
+ case libcontainer.Running:
+ fmt.Fprintln(os.Stderr, "cannot start an already running container")
+ hasError = true
+ default:
+ fmt.Fprintf(os.Stderr, "cannot start a container in the %s state\n", status)
+ hasError = true
}
}
- spec, err := loadSpec(specConfig)
- if err != nil {
- fatal(err)
- }
- notifySocket := os.Getenv("NOTIFY_SOCKET")
- if notifySocket != "" {
- setupSdNotify(spec, notifySocket)
+ if hasError {
+ return fmt.Errorf("one or more of container start failed")
}
-
- if os.Geteuid() != 0 {
- fatalf("runc should be run as root")
- }
-
- status, err := startContainer(context, spec)
- if err != nil {
- fatal(err)
- }
- // exit with the container's exit status so any external supervisor is
- // notified of the exit with the correct exit status.
- os.Exit(status)
+ return nil
},
}
-
-func init() {
- if len(os.Args) > 1 && os.Args[1] == "init" {
- runtime.GOMAXPROCS(1)
- runtime.LockOSThread()
- }
-}
-
-var initCommand = cli.Command{
- Name: "init",
- Usage: `initialize the namespaces and launch the process (do not call it outside of runc)`,
- Action: func(context *cli.Context) {
- factory, _ := libcontainer.New("")
- if err := factory.StartInitialization(); err != nil {
- // as the error is sent back to the parent there is no need to log
- // or write it to stderr because the parent process will handle this
- os.Exit(1)
- }
- panic("libcontainer: container init failed to exec")
- },
-}
-
-func startContainer(context *cli.Context, spec *specs.Spec) (int, error) {
- id := context.Args().First()
- if id == "" {
- return -1, errEmptyID
- }
- container, err := createContainer(context, id, spec)
- if err != nil {
- return -1, err
- }
- detach := context.Bool("detach")
- // Support on-demand socket activation by passing file descriptors into the container init process.
- listenFDs := []*os.File{}
- if os.Getenv("LISTEN_FDS") != "" {
- listenFDs = activation.Files(false)
- }
- r := &runner{
- enableSubreaper: !context.Bool("no-subreaper"),
- shouldDestroy: true,
- container: container,
- listenFDs: listenFDs,
- console: context.String("console"),
- detach: detach,
- pidFile: context.String("pid-file"),
- }
- return r.run(&spec.Process)
-}
diff --git a/vendor/github.com/opencontainers/runc/state.go b/vendor/github.com/opencontainers/runc/state.go
index 50cb5d95..718813c3 100644
--- a/vendor/github.com/opencontainers/runc/state.go
+++ b/vendor/github.com/opencontainers/runc/state.go
@@ -5,33 +5,12 @@ package main
import (
"encoding/json"
"os"
- "time"
- "github.com/codegangsta/cli"
+ "github.com/opencontainers/runc/libcontainer"
"github.com/opencontainers/runc/libcontainer/utils"
+ "github.com/urfave/cli"
)
-// cState represents the platform agnostic pieces relating to a running
-// container's status and state. Note: The fields in this structure adhere to
-// the opencontainers/runtime-spec/specs-go requirement for json fields that must be returned
-// in a state command.
-type cState struct {
- // Version is the OCI version for the container
- Version string `json:"ociVersion"`
- // ID is the container ID
- ID string `json:"id"`
- // InitProcessPid is the init process id in the parent namespace
- InitProcessPid int `json:"pid"`
- // Bundle is the path on the filesystem to the bundle
- Bundle string `json:"bundlePath"`
- // Rootfs is a path to a directory containing the container's root filesystem.
- Rootfs string `json:"rootfsPath"`
- // Status is the current status of the container, running, paused, ...
- Status string `json:"status"`
- // Created is the unix timestamp for the creation time of the container in UTC
- Created time.Time `json:"created"`
-}
-
var stateCommand = cli.Command{
Name: "state",
Usage: "output the state of a container",
@@ -40,31 +19,42 @@ var stateCommand = cli.Command{
Where "" is your name for the instance of the container.`,
Description: `The state command outputs current state information for the
instance of a container.`,
- Action: func(context *cli.Context) {
+ Action: func(context *cli.Context) error {
+ if err := checkArgs(context, 1, exactArgs); err != nil {
+ return err
+ }
container, err := getContainer(context)
if err != nil {
- fatal(err)
+ return err
}
containerStatus, err := container.Status()
if err != nil {
- fatal(err)
+ return err
}
state, err := container.State()
if err != nil {
- fatal(err)
+ return err
}
- cs := cState{
+ pid := state.BaseState.InitProcessPid
+ if containerStatus == libcontainer.Stopped {
+ pid = 0
+ }
+ bundle, annotations := utils.Annotations(state.Config.Labels)
+ cs := containerState{
Version: state.BaseState.Config.Version,
ID: state.BaseState.ID,
- InitProcessPid: state.BaseState.InitProcessPid,
+ InitProcessPid: pid,
Status: containerStatus.String(),
- Bundle: utils.SearchLabels(state.Config.Labels, "bundle"),
+ Bundle: bundle,
Rootfs: state.BaseState.Config.Rootfs,
- Created: state.BaseState.Created}
+ Created: state.BaseState.Created,
+ Annotations: annotations,
+ }
data, err := json.MarshalIndent(cs, "", " ")
if err != nil {
- fatal(err)
+ return err
}
os.Stdout.Write(data)
+ return nil
},
}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/README.md b/vendor/github.com/opencontainers/runc/tests/integration/README.md
new file mode 100644
index 00000000..c58788af
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/README.md
@@ -0,0 +1,83 @@
+# runc Integration Tests
+
+Integration tests provide end-to-end testing of runc.
+
+Note that integration tests do **not** replace unit tests.
+
+As a rule of thumb, code should be tested thoroughly with unit tests.
+Integration tests on the other hand are meant to test a specific feature end
+to end.
+
+Integration tests are written in *bash* using the
+[bats](https://github.com/sstephenson/bats) framework.
+
+## Running integration tests
+
+The easiest way to run integration tests is with Docker:
+```
+$ make integration
+```
+Alternatively, you can run integration tests directly on your host through make:
+```
+$ sudo make localintegration
+```
+Or you can just run them directly using bats
+```
+$ sudo bats tests/integration
+```
+To run a single test bucket:
+```
+$ make integration TESTFLAGS="/checkpoint.bats"
+```
+
+
+To run them on your host, you will need to setup a development environment plus
+[bats](https://github.com/sstephenson/bats#installing-bats-from-source)
+For example:
+```
+$ cd ~/go/src/github.com
+$ git clone https://github.com/sstephenson/bats.git
+$ cd bats
+$ ./install.sh /usr/local
+```
+
+> **Note**: There are known issues running the integration tests using
+> **devicemapper** as a storage driver, make sure that your docker daemon
+> is using **aufs** if you want to successfully run the integration tests.
+
+## Writing integration tests
+
+[helper functions]
+(https://github.com/opencontainers/runc/blob/master/test/integration/helpers.bash)
+are provided in order to facilitate writing tests.
+
+```sh
+#!/usr/bin/env bats
+
+# This will load the helpers.
+load helpers
+
+# setup is called at the beginning of every test.
+function setup() {
+ # see functions teardown_hello and setup_hello in helpers.bash, used to
+ # create a pristine environment for running your tests
+ teardown_hello
+ setup_hello
+}
+
+# teardown is called at the end of every test.
+function teardown() {
+ teardown_hello
+}
+
+@test "this is a simple test" {
+ runc run containerid
+ # "The runc macro" automatically populates $status, $output and $lines.
+ # Please refer to bats documentation to find out more.
+ [ "$status" -eq 0 ]
+
+ # check expected output
+ [[ "${output}" == *"Hello"* ]]
+}
+
+```
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/cgroups.bats b/vendor/github.com/opencontainers/runc/tests/integration/cgroups.bats
new file mode 100644
index 00000000..9ab6f432
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/cgroups.bats
@@ -0,0 +1,78 @@
+#!/usr/bin/env bats
+
+load helpers
+
+TEST_CGROUP_NAME="runc-cgroups-integration-test"
+CGROUP_MEMORY="${CGROUP_MEMORY_BASE_PATH}/${TEST_CGROUP_NAME}"
+
+function teardown() {
+ rm -f $BATS_TMPDIR/runc-update-integration-test.json
+ teardown_running_container test_cgroups_kmem
+ teardown_busybox
+}
+
+function setup() {
+ teardown
+ setup_busybox
+}
+
+function check_cgroup_value() {
+ cgroup=$1
+ source=$2
+ expected=$3
+
+ current=$(cat $cgroup/$source)
+ echo $cgroup/$source
+ echo "current" $current "!?" "$expected"
+ [ "$current" -eq "$expected" ]
+}
+
+@test "runc update --kernel-memory (initialized)" {
+ requires cgroups_kmem
+ # Add cgroup path
+ sed -i 's/\("linux": {\)/\1\n "cgroupsPath": "\/runc-cgroups-integration-test",/' ${BUSYBOX_BUNDLE}/config.json
+
+ # Set some initial known values
+ DATA=$(cat <<-EOF
+ "memory": {
+ "kernel": 16777216
+ },
+EOF
+ )
+ DATA=$(echo ${DATA} | sed 's/\n/\\n/g')
+ sed -i "s/\(\"resources\": {\)/\1\n${DATA}/" ${BUSYBOX_BUNDLE}/config.json
+
+ # run a detached busybox to work with
+ runc run -d --console-socket $CONSOLE_SOCKET test_cgroups_kmem
+ [ "$status" -eq 0 ]
+ wait_for_container 15 1 test_cgroups_kmem
+
+ # update kernel memory limit
+ runc update test_cgroups_kmem --kernel-memory 50331648
+ [ "$status" -eq 0 ]
+
+ # check the value
+ check_cgroup_value $CGROUP_MEMORY "memory.kmem.limit_in_bytes" 50331648
+}
+
+@test "runc update --kernel-memory (uninitialized)" {
+ requires cgroups_kmem
+ # Add cgroup path
+ sed -i 's/\("linux": {\)/\1\n "cgroupsPath": "\/runc-cgroups-integration-test",/' ${BUSYBOX_BUNDLE}/config.json
+
+ # run a detached busybox to work with
+ runc run -d --console-socket $CONSOLE_SOCKET test_cgroups_kmem
+ [ "$status" -eq 0 ]
+ wait_for_container 15 1 test_cgroups_kmem
+
+ # update kernel memory limit
+ runc update test_cgroups_kmem --kernel-memory 50331648
+ # Since kernel 4.6, we can update kernel memory without initialization
+ # because it's accounted by default.
+ if [ "$KERNEL_MAJOR" -lt 4 ] || [ "$KERNEL_MAJOR" -eq 4 -a "$KERNEL_MINOR" -le 5 ]; then
+ [ ! "$status" -eq 0 ]
+ else
+ [ "$status" -eq 0 ]
+ check_cgroup_value $CGROUP_MEMORY "memory.kmem.limit_in_bytes" 50331648
+ fi
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/checkpoint.bats b/vendor/github.com/opencontainers/runc/tests/integration/checkpoint.bats
new file mode 100644
index 00000000..4a369396
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/checkpoint.bats
@@ -0,0 +1,59 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ teardown_busybox
+ setup_busybox
+}
+
+function teardown() {
+ teardown_busybox
+}
+
+@test "checkpoint and restore" {
+ requires criu
+
+ # criu does not work with external terminals so..
+ # setting terminal and root:readonly: to false
+ sed -i 's;"terminal": true;"terminal": false;' config.json
+ sed -i 's;"readonly": true;"readonly": false;' config.json
+ sed -i 's/"sh"/"sh","-c","while :; do date; sleep 1; done"/' config.json
+
+ (
+ # run busybox (not detached)
+ runc run test_busybox
+ [ "$status" -eq 0 ]
+ ) &
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ runc state test_busybox
+ [ "$status" -eq 0 ]
+ [[ "${output}" == *"running"* ]]
+
+ # checkpoint the running container
+ runc --criu "$CRIU" checkpoint test_busybox
+ # if you are having problems getting criu to work uncomment the following dump:
+ #cat /run/opencontainer/containers/test_busybox/criu.work/dump.log
+ [ "$status" -eq 0 ]
+
+ # after checkpoint busybox is no longer running
+ runc state test_busybox
+ [ "$status" -ne 0 ]
+
+ # restore from checkpoint
+ (
+ runc --criu "$CRIU" restore test_busybox
+ [ "$status" -eq 0 ]
+ ) &
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ # busybox should be back up and running
+ runc state test_busybox
+ [ "$status" -eq 0 ]
+ [[ "${output}" == *"running"* ]]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/create.bats b/vendor/github.com/opencontainers/runc/tests/integration/create.bats
new file mode 100644
index 00000000..abd4da24
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/create.bats
@@ -0,0 +1,89 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ teardown_busybox
+ setup_busybox
+}
+
+function teardown() {
+ teardown_busybox
+}
+
+@test "runc create" {
+ runc create --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ testcontainer test_busybox created
+
+ # start the command
+ runc start test_busybox
+ [ "$status" -eq 0 ]
+
+ testcontainer test_busybox running
+}
+
+@test "runc create exec" {
+ runc create --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ testcontainer test_busybox created
+
+ runc exec test_busybox true
+ [ "$status" -eq 0 ]
+
+ testcontainer test_busybox created
+
+ # start the command
+ runc start test_busybox
+ [ "$status" -eq 0 ]
+
+ testcontainer test_busybox running
+}
+
+@test "runc create --pid-file" {
+ runc create --pid-file pid.txt --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ testcontainer test_busybox created
+
+ # check pid.txt was generated
+ [ -e pid.txt ]
+
+ run cat pid.txt
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} == $(__runc state test_busybox | jq '.pid') ]]
+
+ # start the command
+ runc start test_busybox
+ [ "$status" -eq 0 ]
+
+ testcontainer test_busybox running
+}
+
+@test "runc create --pid-file with new CWD" {
+ # create pid_file directory as the CWD
+ run mkdir pid_file
+ [ "$status" -eq 0 ]
+ run cd pid_file
+ [ "$status" -eq 0 ]
+
+ runc create --pid-file pid.txt -b $BUSYBOX_BUNDLE --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ testcontainer test_busybox created
+
+ # check pid.txt was generated
+ [ -e pid.txt ]
+
+ run cat pid.txt
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} == $(__runc state test_busybox | jq '.pid') ]]
+
+ # start the command
+ runc start test_busybox
+ [ "$status" -eq 0 ]
+
+ testcontainer test_busybox running
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/debug.bats b/vendor/github.com/opencontainers/runc/tests/integration/debug.bats
new file mode 100644
index 00000000..971bc7e1
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/debug.bats
@@ -0,0 +1,70 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ teardown_hello
+ setup_hello
+}
+
+function teardown() {
+ teardown_hello
+}
+
+@test "global --debug" {
+ # run hello-world
+ runc --debug run test_hello
+ echo "${output}"
+ [ "$status" -eq 0 ]
+}
+
+@test "global --debug to --log" {
+ # run hello-world
+ runc --log log.out --debug run test_hello
+ [ "$status" -eq 0 ]
+
+ # check output does not include debug info
+ [[ "${output}" != *"level=debug"* ]]
+
+ # check log.out was generated
+ [ -e log.out ]
+
+ # check expected debug output was sent to log.out
+ run cat log.out
+ [ "$status" -eq 0 ]
+ [[ "${output}" == *"level=debug"* ]]
+}
+
+@test "global --debug to --log --log-format 'text'" {
+ # run hello-world
+ runc --log log.out --log-format "text" --debug run test_hello
+ [ "$status" -eq 0 ]
+
+ # check output does not include debug info
+ [[ "${output}" != *"level=debug"* ]]
+
+ # check log.out was generated
+ [ -e log.out ]
+
+ # check expected debug output was sent to log.out
+ run cat log.out
+ [ "$status" -eq 0 ]
+ [[ "${output}" == *"level=debug"* ]]
+}
+
+@test "global --debug to --log --log-format 'json'" {
+ # run hello-world
+ runc --log log.out --log-format "json" --debug run test_hello
+ [ "$status" -eq 0 ]
+
+ # check output does not include debug info
+ [[ "${output}" != *"level=debug"* ]]
+
+ # check log.out was generated
+ [ -e log.out ]
+
+ # check expected debug output was sent to log.out
+ run cat log.out
+ [ "$status" -eq 0 ]
+ [[ "${output}" == *'"level":"debug"'* ]]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/delete.bats b/vendor/github.com/opencontainers/runc/tests/integration/delete.bats
new file mode 100644
index 00000000..61a9c4c9
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/delete.bats
@@ -0,0 +1,109 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ teardown_busybox
+ setup_busybox
+}
+
+function teardown() {
+ teardown_busybox
+}
+
+@test "runc delete" {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ testcontainer test_busybox running
+
+ runc kill test_busybox KILL
+ # wait for busybox to be in the destroyed state
+ retry 10 1 eval "__runc state test_busybox | grep -q 'stopped'"
+
+ # delete test_busybox
+ runc delete test_busybox
+
+ runc state test_busybox
+ [ "$status" -ne 0 ]
+}
+
+@test "runc delete --force" {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ testcontainer test_busybox running
+
+ # force delete test_busybox
+ runc delete --force test_busybox
+
+ runc state test_busybox
+ [ "$status" -ne 0 ]
+}
+
+@test "run delete with multi-containers" {
+ # create busybox1 detached
+ runc create --console-socket $CONSOLE_SOCKET test_busybox1
+ [ "$status" -eq 0 ]
+
+ testcontainer test_busybox1 created
+
+ # run busybox2 detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox2
+ [ "$status" -eq 0 ]
+
+ wait_for_container 15 1 test_busybox2
+ testcontainer test_busybox2 running
+
+ # delete both test_busybox1 and test_busybox2 container
+ runc delete test_busybox1 test_busybox2
+
+ runc state test_busybox1
+ [ "$status" -ne 0 ]
+
+ runc state test_busybox2
+ [ "$status" -eq 0 ]
+
+ runc kill test_busybox2 KILL
+ # wait for busybox2 to be in the destroyed state
+ retry 10 1 eval "__runc state test_busybox2 | grep -q 'stopped'"
+
+ # delete test_busybox2
+ runc delete test_busybox2
+
+ runc state test_busybox2
+ [ "$status" -ne 0 ]
+}
+
+
+@test "run delete --force with multi-containers" {
+ # create busybox1 detached
+ runc create --console-socket $CONSOLE_SOCKET test_busybox1
+ [ "$status" -eq 0 ]
+
+ testcontainer test_busybox1 created
+
+ # run busybox2 detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox2
+ [ "$status" -eq 0 ]
+
+ wait_for_container 15 1 test_busybox2
+ testcontainer test_busybox2 running
+
+ # delete both test_busybox1 and test_busybox2 container
+ runc delete --force test_busybox1 test_busybox2
+
+ runc state test_busybox1
+ [ "$status" -ne 0 ]
+
+ runc state test_busybox2
+ [ "$status" -ne 0 ]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/events.bats b/vendor/github.com/opencontainers/runc/tests/integration/events.bats
new file mode 100644
index 00000000..182b721b
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/events.bats
@@ -0,0 +1,109 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ teardown_busybox
+ setup_busybox
+}
+
+function teardown() {
+ teardown_busybox
+}
+
+@test "events --stats" {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ # generate stats
+ runc events --stats test_busybox
+ [ "$status" -eq 0 ]
+ [[ "${lines[0]}" == [\{]"\"type\""[:]"\"stats\""[,]"\"id\""[:]"\"test_busybox\""[,]* ]]
+ [[ "${lines[0]}" == *"data"* ]]
+}
+
+@test "events --interval default " {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ # spawn two sub processes (shells)
+ # the first sub process is an event logger that sends stats events to events.log
+ # the second sub process waits for an event that incudes test_busybox then
+ # kills the test_busybox container which causes the event logger to exit
+ (__runc events test_busybox > events.log) &
+ (
+ retry 10 1 eval "grep -q 'test_busybox' events.log"
+ teardown_running_container test_busybox
+ ) &
+ wait # wait for the above sub shells to finish
+
+ [ -e events.log ]
+
+ run cat events.log
+ [ "$status" -eq 0 ]
+ [[ "${lines[0]}" == [\{]"\"type\""[:]"\"stats\""[,]"\"id\""[:]"\"test_busybox\""[,]* ]]
+ [[ "${lines[0]}" == *"data"* ]]
+}
+
+@test "events --interval 1s " {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ # spawn two sub processes (shells)
+ # the first sub process is an event logger that sends stats events to events.log once a second
+ # the second sub process tries 3 times for an event that incudes test_busybox
+ # pausing 1s between each attempt then kills the test_busybox container which
+ # causes the event logger to exit
+ (__runc events --interval 1s test_busybox > events.log) &
+ (
+ retry 3 1 eval "grep -q 'test_busybox' events.log"
+ teardown_running_container test_busybox
+ ) &
+ wait # wait for the above sub shells to finish
+
+ [ -e events.log ]
+
+ run eval "grep -q 'test_busybox' events.log"
+ [ "$status" -eq 0 ]
+}
+
+@test "events --interval 100ms " {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ #prove there is no carry over of events.log from a prior test
+ [ ! -e events.log ]
+
+ # spawn two sub processes (shells)
+ # the first sub process is an event logger that sends stats events to events.log once every 100ms
+ # the second sub process tries 3 times for an event that incudes test_busybox
+ # pausing 100s between each attempt then kills the test_busybox container which
+ # causes the event logger to exit
+ (__runc events --interval 100ms test_busybox > events.log) &
+ (
+ retry 3 0.100 eval "grep -q 'test_busybox' events.log"
+ teardown_running_container test_busybox
+ ) &
+ wait # wait for the above sub shells to finish
+
+ [ -e events.log ]
+
+ run eval "grep -q 'test_busybox' events.log"
+ [ "$status" -eq 0 ]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/exec.bats b/vendor/github.com/opencontainers/runc/tests/integration/exec.bats
new file mode 100644
index 00000000..ba60ea17
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/exec.bats
@@ -0,0 +1,125 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ teardown_busybox
+ setup_busybox
+}
+
+function teardown() {
+ teardown_busybox
+}
+
+@test "runc exec" {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ wait_for_container 15 1 test_busybox
+
+ runc exec test_busybox echo Hello from exec
+ [ "$status" -eq 0 ]
+ echo text echoed = "'""${output}""'"
+ [[ "${output}" == *"Hello from exec"* ]]
+}
+
+@test "runc exec --pid-file" {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ wait_for_container 15 1 test_busybox
+
+ runc exec --pid-file pid.txt test_busybox echo Hello from exec
+ [ "$status" -eq 0 ]
+ echo text echoed = "'""${output}""'"
+ [[ "${output}" == *"Hello from exec"* ]]
+
+ # check pid.txt was generated
+ [ -e pid.txt ]
+
+ run cat pid.txt
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ [0-9]+ ]]
+ [[ ${lines[0]} != $(__runc state test_busybox | jq '.pid') ]]
+}
+
+@test "runc exec --pid-file with new CWD" {
+ # create pid_file directory as the CWD
+ run mkdir pid_file
+ [ "$status" -eq 0 ]
+ run cd pid_file
+ [ "$status" -eq 0 ]
+
+ # run busybox detached
+ runc run -d -b $BUSYBOX_BUNDLE --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ wait_for_container 15 1 test_busybox
+
+ runc exec --pid-file pid.txt test_busybox echo Hello from exec
+ [ "$status" -eq 0 ]
+ echo text echoed = "'""${output}""'"
+ [[ "${output}" == *"Hello from exec"* ]]
+
+ # check pid.txt was generated
+ [ -e pid.txt ]
+
+ run cat pid.txt
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ [0-9]+ ]]
+ [[ ${lines[0]} != $(__runc state test_busybox | jq '.pid') ]]
+}
+
+@test "runc exec ls -la" {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ wait_for_container 15 1 test_busybox
+
+ runc exec test_busybox ls -la
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} == *"total"* ]]
+ [[ ${lines[1]} == *"."* ]]
+ [[ ${lines[2]} == *".."* ]]
+}
+
+@test "runc exec ls -la with --cwd" {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ wait_for_container 15 1 test_busybox
+
+ runc exec --cwd /bin test_busybox pwd
+ [ "$status" -eq 0 ]
+ [[ ${output} == "/bin" ]]
+}
+
+@test "runc exec --env" {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ wait_for_container 15 1 test_busybox
+
+ runc exec --env RUNC_EXEC_TEST=true test_busybox env
+ [ "$status" -eq 0 ]
+
+ [[ ${output} == *"RUNC_EXEC_TEST=true"* ]]
+}
+
+@test "runc exec --user" {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ wait_for_container 15 1 test_busybox
+
+ runc exec --user 1000:1000 test_busybox id
+ [ "$status" -eq 0 ]
+
+ [[ ${output} == "uid=1000 gid=1000" ]]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/help.bats b/vendor/github.com/opencontainers/runc/tests/integration/help.bats
new file mode 100644
index 00000000..ca404f34
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/help.bats
@@ -0,0 +1,86 @@
+#!/usr/bin/env bats
+
+load helpers
+
+@test "runc -h" {
+ runc -h
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ NAME:+ ]]
+ [[ ${lines[1]} =~ runc\ '-'\ Open\ Container\ Initiative\ runtime+ ]]
+
+ runc --help
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ NAME:+ ]]
+ [[ ${lines[1]} =~ runc\ '-'\ Open\ Container\ Initiative\ runtime+ ]]
+}
+
+@test "runc command -h" {
+ runc checkpoint -h
+ [ "$status" -eq 0 ]
+ [[ ${lines[1]} =~ runc\ checkpoint+ ]]
+
+ runc delete -h
+ [ "$status" -eq 0 ]
+ [[ ${lines[1]} =~ runc\ delete+ ]]
+
+ runc events -h
+ [ "$status" -eq 0 ]
+ [[ ${lines[1]} =~ runc\ events+ ]]
+
+ runc exec -h
+ [ "$status" -eq 0 ]
+ [[ ${lines[1]} =~ runc\ exec+ ]]
+
+ runc kill -h
+ [ "$status" -eq 0 ]
+ [[ ${lines[1]} =~ runc\ kill+ ]]
+
+ runc list -h
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ NAME:+ ]]
+ [[ ${lines[1]} =~ runc\ list+ ]]
+
+ runc list --help
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ NAME:+ ]]
+ [[ ${lines[1]} =~ runc\ list+ ]]
+
+ runc pause -h
+ [ "$status" -eq 0 ]
+ [[ ${lines[1]} =~ runc\ pause+ ]]
+
+ runc restore -h
+ [ "$status" -eq 0 ]
+ [[ ${lines[1]} =~ runc\ restore+ ]]
+
+ runc resume -h
+ [ "$status" -eq 0 ]
+ [[ ${lines[1]} =~ runc\ resume+ ]]
+
+ runc spec -h
+ [ "$status" -eq 0 ]
+ [[ ${lines[1]} =~ runc\ spec+ ]]
+
+ runc start -h
+ [ "$status" -eq 0 ]
+ [[ ${lines[1]} =~ runc\ start+ ]]
+
+ runc run -h
+ [ "$status" -eq 0 ]
+ [[ ${lines[1]} =~ runc\ run+ ]]
+
+ runc state -h
+ [ "$status" -eq 0 ]
+ [[ ${lines[1]} =~ runc\ state+ ]]
+
+ runc update -h
+ [ "$status" -eq 0 ]
+ [[ ${lines[1]} =~ runc\ update+ ]]
+
+}
+
+@test "runc foo -h" {
+ runc foo -h
+ [ "$status" -ne 0 ]
+ [[ "${output}" == *"No help topic for 'foo'"* ]]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/helpers.bash b/vendor/github.com/opencontainers/runc/tests/integration/helpers.bash
new file mode 100644
index 00000000..e4c2cb93
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/helpers.bash
@@ -0,0 +1,233 @@
+#!/bin/bash
+
+# Root directory of integration tests.
+INTEGRATION_ROOT=$(dirname "$(readlink -f "$BASH_SOURCE")")
+RUNC="${INTEGRATION_ROOT}/../../runc"
+RECVTTY="${INTEGRATION_ROOT}/../../contrib/cmd/recvtty/recvtty"
+GOPATH="${INTEGRATION_ROOT}/../../../.."
+
+# Test data path.
+TESTDATA="${INTEGRATION_ROOT}/testdata"
+
+# Busybox image
+BUSYBOX_IMAGE="$BATS_TMPDIR/busybox.tar"
+BUSYBOX_BUNDLE="$BATS_TMPDIR/busyboxtest"
+
+# hello-world in tar format
+HELLO_IMAGE="$TESTDATA/hello-world.tar"
+HELLO_BUNDLE="$BATS_TMPDIR/hello-world"
+
+# CRIU PATH
+CRIU="$(which criu)"
+
+# Kernel version
+KERNEL_VERSION="$(uname -r)"
+KERNEL_MAJOR="${KERNEL_VERSION%%.*}"
+KERNEL_MINOR="${KERNEL_VERSION#$KERNEL_MAJOR.}"
+KERNEL_MINOR="${KERNEL_MINOR%%.*}"
+
+# Root state path.
+ROOT="$BATS_TMPDIR/runc"
+
+# Path to console socket.
+CONSOLE_SOCKET="$BATS_TMPDIR/console.sock"
+
+# Cgroup mount
+CGROUP_MEMORY_BASE_PATH=$(grep "cgroup" /proc/self/mountinfo | gawk 'toupper($NF) ~ /\/ { print $5; exit }')
+CGROUP_CPU_BASE_PATH=$(grep "cgroup" /proc/self/mountinfo | gawk 'toupper($NF) ~ /\/ { print $5; exit }')
+
+# CONFIG_MEMCG_KMEM support
+KMEM="${CGROUP_MEMORY_BASE_PATH}/memory.kmem.limit_in_bytes"
+RT_PERIOD="${CGROUP_CPU_BASE_PATH}/cpu.rt_period_us"
+
+# Wrapper for runc.
+function runc() {
+ run __runc "$@"
+
+ # Some debug information to make life easier. bats will only print it if the
+ # test failed, in which case the output is useful.
+ echo "runc $@ (status=$status):" >&2
+ echo "$output" >&2
+}
+
+# Raw wrapper for runc.
+function __runc() {
+ "$RUNC" --root "$ROOT" "$@"
+}
+
+# Fails the current test, providing the error given.
+function fail() {
+ echo "$@" >&2
+ exit 1
+}
+
+# Allows a test to specify what things it requires. If the environment can't
+# support it, the test is skipped with a message.
+function requires() {
+ for var in "$@"; do
+ case $var in
+ criu)
+ if [ ! -e "$CRIU" ]; then
+ skip "Test requires ${var}."
+ fi
+ ;;
+ cgroups_kmem)
+ if [ ! -e "$KMEM" ]; then
+ skip "Test requires ${var}."
+ fi
+ ;;
+ cgroups_rt)
+ if [ ! -e "$RT_PERIOD" ]; then
+ skip "Test requires ${var}."
+ fi
+ ;;
+ *)
+ fail "BUG: Invalid requires ${var}."
+ ;;
+ esac
+ done
+}
+
+# Retry a command $1 times until it succeeds. Wait $2 seconds between retries.
+function retry() {
+ local attempts=$1
+ shift
+ local delay=$1
+ shift
+ local i
+
+ for ((i = 0; i < attempts; i++)); do
+ run "$@"
+ if [[ "$status" -eq 0 ]]; then
+ return 0
+ fi
+ sleep $delay
+ done
+
+ echo "Command \"$@\" failed $attempts times. Output: $output"
+ false
+}
+
+# retry until the given container has state
+function wait_for_container() {
+ local attempts=$1
+ local delay=$2
+ local cid=$3
+ local i
+
+ for ((i = 0; i < attempts; i++)); do
+ runc state $cid
+ if [[ "$status" -eq 0 ]]; then
+ return 0
+ fi
+ sleep $delay
+ done
+
+ echo "runc state failed to return state $statecheck $attempts times. Output: $output"
+ false
+}
+
+# retry until the given container has state
+function wait_for_container_inroot() {
+ local attempts=$1
+ local delay=$2
+ local cid=$3
+ local i
+
+ for ((i = 0; i < attempts; i++)); do
+ ROOT=$4 runc state $cid
+ if [[ "$status" -eq 0 ]]; then
+ return 0
+ fi
+ sleep $delay
+ done
+
+ echo "runc state failed to return state $statecheck $attempts times. Output: $output"
+ false
+}
+
+function testcontainer() {
+ # test state of container
+ runc state $1
+ [ "$status" -eq 0 ]
+ [[ "${output}" == *"$2"* ]]
+}
+
+function setup_recvtty() {
+ # We need to start recvtty in the background, so we double fork in the shell.
+ ("$RECVTTY" --pid-file "$BATS_TMPDIR/recvtty.pid" --mode null "$CONSOLE_SOCKET" &) &
+}
+
+function teardown_recvtty() {
+ # When we kill recvtty, the container will also be killed.
+ if [ -f "$BATS_TMPDIR/recvtty.pid" ]; then
+ kill -9 $(cat "$BATS_TMPDIR/recvtty.pid")
+ fi
+
+ # Clean up the files that might be left over.
+ rm -f "$BATS_TMPDIR/recvtty.pid"
+ rm -f "$CONSOLE_SOCKET"
+}
+
+function setup_busybox() {
+ setup_recvtty
+ run mkdir "$BUSYBOX_BUNDLE"
+ run mkdir "$BUSYBOX_BUNDLE"/rootfs
+ if [ -e "/testdata/busybox.tar" ]; then
+ BUSYBOX_IMAGE="/testdata/busybox.tar"
+ fi
+ if [ ! -e $BUSYBOX_IMAGE ]; then
+ curl -o $BUSYBOX_IMAGE -sSL 'https://github.com/docker-library/busybox/raw/a0558a9006ce0dd6f6ec5d56cfd3f32ebeeb815f/glibc/busybox.tar.xz'
+ fi
+ tar -C "$BUSYBOX_BUNDLE"/rootfs -xf "$BUSYBOX_IMAGE"
+ cd "$BUSYBOX_BUNDLE"
+ runc spec
+}
+
+function setup_hello() {
+ setup_recvtty
+ run mkdir "$HELLO_BUNDLE"
+ run mkdir "$HELLO_BUNDLE"/rootfs
+ tar -C "$HELLO_BUNDLE"/rootfs -xf "$HELLO_IMAGE"
+ cd "$HELLO_BUNDLE"
+ runc spec
+ sed -i 's;"sh";"/hello";' config.json
+}
+
+function teardown_running_container() {
+ runc list
+ # $1 should be a container name such as "test_busybox"
+ # here we detect "test_busybox "(with one extra blank) to avoid conflict prefix
+ # e.g. "test_busybox" and "test_busybox_update"
+ if [[ "${output}" == *"$1 "* ]]; then
+ runc kill $1 KILL
+ retry 10 1 eval "__runc state '$1' | grep -q 'stopped'"
+ runc delete $1
+ fi
+}
+
+function teardown_running_container_inroot() {
+ ROOT=$2 runc list
+ # $1 should be a container name such as "test_busybox"
+ # here we detect "test_busybox "(with one extra blank) to avoid conflict prefix
+ # e.g. "test_busybox" and "test_busybox_update"
+ if [[ "${output}" == *"$1 "* ]]; then
+ ROOT=$2 runc kill $1 KILL
+ retry 10 1 eval "ROOT='$2' __runc state '$1' | grep -q 'stopped'"
+ ROOT=$2 runc delete $1
+ fi
+}
+
+function teardown_busybox() {
+ cd "$INTEGRATION_ROOT"
+ teardown_recvtty
+ teardown_running_container test_busybox
+ run rm -f -r "$BUSYBOX_BUNDLE"
+}
+
+function teardown_hello() {
+ cd "$INTEGRATION_ROOT"
+ teardown_recvtty
+ teardown_running_container test_hello
+ run rm -f -r "$HELLO_BUNDLE"
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/kill.bats b/vendor/github.com/opencontainers/runc/tests/integration/kill.bats
new file mode 100644
index 00000000..a049de65
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/kill.bats
@@ -0,0 +1,33 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ teardown_busybox
+ setup_busybox
+}
+
+function teardown() {
+ teardown_busybox
+}
+
+
+@test "kill detached busybox" {
+
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ testcontainer test_busybox running
+
+ runc kill test_busybox KILL
+ [ "$status" -eq 0 ]
+
+ retry 10 1 eval "__runc state test_busybox | grep -q 'stopped'"
+
+ runc delete test_busybox
+ [ "$status" -eq 0 ]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/list.bats b/vendor/github.com/opencontainers/runc/tests/integration/list.bats
new file mode 100644
index 00000000..302728a5
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/list.bats
@@ -0,0 +1,59 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ teardown_running_container_inroot test_box1 $HELLO_BUNDLE
+ teardown_running_container_inroot test_box2 $HELLO_BUNDLE
+ teardown_running_container_inroot test_box3 $HELLO_BUNDLE
+ teardown_busybox
+ setup_busybox
+}
+
+function teardown() {
+ teardown_running_container_inroot test_box1 $HELLO_BUNDLE
+ teardown_running_container_inroot test_box2 $HELLO_BUNDLE
+ teardown_running_container_inroot test_box3 $HELLO_BUNDLE
+ teardown_busybox
+}
+
+@test "list" {
+ # run a few busyboxes detached
+ ROOT=$HELLO_BUNDLE runc run -d --console-socket $CONSOLE_SOCKET test_box1
+ [ "$status" -eq 0 ]
+ wait_for_container_inroot 15 1 test_box1 $HELLO_BUNDLE
+
+ ROOT=$HELLO_BUNDLE runc run -d --console-socket $CONSOLE_SOCKET test_box2
+ [ "$status" -eq 0 ]
+ wait_for_container_inroot 15 1 test_box2 $HELLO_BUNDLE
+
+ ROOT=$HELLO_BUNDLE runc run -d --console-socket $CONSOLE_SOCKET test_box3
+ [ "$status" -eq 0 ]
+ wait_for_container_inroot 15 1 test_box3 $HELLO_BUNDLE
+
+ ROOT=$HELLO_BUNDLE runc list
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ ID\ +PID\ +STATUS\ +BUNDLE\ +CREATED+ ]]
+ [[ "${lines[1]}" == *"test_box1"*[0-9]*"running"*$BUSYBOX_BUNDLE*[0-9]* ]]
+ [[ "${lines[2]}" == *"test_box2"*[0-9]*"running"*$BUSYBOX_BUNDLE*[0-9]* ]]
+ [[ "${lines[3]}" == *"test_box3"*[0-9]*"running"*$BUSYBOX_BUNDLE*[0-9]* ]]
+
+ ROOT=$HELLO_BUNDLE runc list -q
+ [ "$status" -eq 0 ]
+ [[ "${lines[0]}" == "test_box1" ]]
+ [[ "${lines[1]}" == "test_box2" ]]
+ [[ "${lines[2]}" == "test_box3" ]]
+
+ ROOT=$HELLO_BUNDLE runc list --format table
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ ID\ +PID\ +STATUS\ +BUNDLE\ +CREATED+ ]]
+ [[ "${lines[1]}" == *"test_box1"*[0-9]*"running"*$BUSYBOX_BUNDLE*[0-9]* ]]
+ [[ "${lines[2]}" == *"test_box2"*[0-9]*"running"*$BUSYBOX_BUNDLE*[0-9]* ]]
+ [[ "${lines[3]}" == *"test_box3"*[0-9]*"running"*$BUSYBOX_BUNDLE*[0-9]* ]]
+
+ ROOT=$HELLO_BUNDLE runc list --format json
+ [ "$status" -eq 0 ]
+ [[ "${lines[0]}" == [\[][\{]"\"ociVersion\""[:]"\""*[0-9][\.]*[0-9][\.]*[0-9]*"\""[,]"\"id\""[:]"\"test_box1\""[,]"\"pid\""[:]*[0-9][,]"\"status\""[:]*"\"running\""[,]"\"bundle\""[:]*$BUSYBOX_BUNDLE*[,]"\"rootfs\""[:]"\""*"\""[,]"\"created\""[:]*[0-9]*[\}]* ]]
+ [[ "${lines[0]}" == *[,][\{]"\"ociVersion\""[:]"\""*[0-9][\.]*[0-9][\.]*[0-9]*"\""[,]"\"id\""[:]"\"test_box2\""[,]"\"pid\""[:]*[0-9][,]"\"status\""[:]*"\"running\""[,]"\"bundle\""[:]*$BUSYBOX_BUNDLE*[,]"\"rootfs\""[:]"\""*"\""[,]"\"created\""[:]*[0-9]*[\}]* ]]
+ [[ "${lines[0]}" == *[,][\{]"\"ociVersion\""[:]"\""*[0-9][\.]*[0-9][\.]*[0-9]*"\""[,]"\"id\""[:]"\"test_box3\""[,]"\"pid\""[:]*[0-9][,]"\"status\""[:]*"\"running\""[,]"\"bundle\""[:]*$BUSYBOX_BUNDLE*[,]"\"rootfs\""[:]"\""*"\""[,]"\"created\""[:]*[0-9]*[\}][\]] ]]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/mask.bats b/vendor/github.com/opencontainers/runc/tests/integration/mask.bats
new file mode 100644
index 00000000..074b0f2e
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/mask.bats
@@ -0,0 +1,63 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ teardown_busybox
+ setup_busybox
+
+ # Create fake rootfs.
+ mkdir rootfs/testdir
+ echo "Forbidden information!" > rootfs/testfile
+
+ # add extra masked paths
+ sed -i 's;"maskedPaths": \[;"maskedPaths": \["/testdir","/testfile",;g' config.json
+}
+
+function teardown() {
+ teardown_busybox
+}
+
+@test "mask paths [file]" {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ wait_for_container 15 1 test_busybox
+
+ runc exec test_busybox cat /testfile
+ [ "$status" -eq 0 ]
+ [[ "${output}" == "" ]]
+
+ runc exec test_busybox rm -f /testfile
+ [ "$status" -eq 1 ]
+ [[ "${output}" == *"Read-only file system"* ]]
+
+ runc exec test_busybox umount /testfile
+ [ "$status" -eq 1 ]
+ [[ "${output}" == *"Operation not permitted"* ]]
+}
+
+@test "mask paths [directory]" {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ wait_for_container 15 1 test_busybox
+
+ runc exec test_busybox ls /testdir
+ [ "$status" -eq 0 ]
+ [[ "${output}" == "" ]]
+
+ runc exec test_busybox touch /testdir/foo
+ [ "$status" -eq 1 ]
+ [[ "${output}" == *"Read-only file system"* ]]
+
+ runc exec test_busybox rm -rf /testdir
+ [ "$status" -eq 1 ]
+ [[ "${output}" == *"Read-only file system"* ]]
+
+ runc exec test_busybox umount /testdir
+ [ "$status" -eq 1 ]
+ [[ "${output}" == *"Operation not permitted"* ]]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/pause.bats b/vendor/github.com/opencontainers/runc/tests/integration/pause.bats
new file mode 100644
index 00000000..e657d0a1
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/pause.bats
@@ -0,0 +1,112 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ teardown_busybox
+ setup_busybox
+}
+
+function teardown() {
+ teardown_busybox
+}
+
+@test "runc pause and resume" {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ wait_for_container 15 1 test_busybox
+
+ # pause busybox
+ runc pause test_busybox
+ [ "$status" -eq 0 ]
+
+ # test state of busybox is paused
+ testcontainer test_busybox paused
+
+ # resume busybox
+ runc resume test_busybox
+ [ "$status" -eq 0 ]
+
+ # test state of busybox is back to running
+ testcontainer test_busybox running
+}
+
+@test "runc pause and resume with multi-container" {
+ # run test_busybox1 detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox1
+ [ "$status" -eq 0 ]
+
+ wait_for_container 15 1 test_busybox1
+
+ # run test_busybox2 detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox2
+ [ "$status" -eq 0 ]
+
+ wait_for_container 15 1 test_busybox2
+
+ # pause test_busybox1 and test_busybox2
+ runc pause test_busybox1 test_busybox2
+ [ "$status" -eq 0 ]
+
+ # test state of test_busybox1 and test_busybox2 is paused
+ testcontainer test_busybox1 paused
+ testcontainer test_busybox2 paused
+
+ # resume test_busybox1 and test_busybox2
+ runc resume test_busybox1 test_busybox2
+ [ "$status" -eq 0 ]
+
+ # test state of two containers is back to running
+ testcontainer test_busybox1 running
+ testcontainer test_busybox2 running
+
+ # delete test_busybox1 and test_busybox2
+ runc delete --force test_busybox1 test_busybox2
+
+ runc state test_busybox1
+ [ "$status" -ne 0 ]
+
+ runc state test_busybox2
+ [ "$status" -ne 0 ]
+}
+
+@test "runc pause and resume with nonexist container" {
+ # run test_busybox1 detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox1
+ [ "$status" -eq 0 ]
+
+ wait_for_container 15 1 test_busybox1
+
+ # run test_busybox2 detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox2
+ [ "$status" -eq 0 ]
+
+ wait_for_container 15 1 test_busybox2
+
+ # pause test_busybox1, test_busybox2 and nonexistent container
+ runc pause test_busybox1 test_busybox2 nonexistent
+ [ "$status" -ne 0 ]
+
+ # test state of test_busybox1 and test_busybox2 is paused
+ testcontainer test_busybox1 paused
+ testcontainer test_busybox2 paused
+
+ # resume test_busybox1, test_busybox2 and nonexistent container
+ runc resume test_busybox1 test_busybox2 nonexistent
+ [ "$status" -ne 0 ]
+
+ # test state of two containers is back to running
+ testcontainer test_busybox1 running
+ testcontainer test_busybox2 running
+
+ # delete test_busybox1 and test_busybox2
+ runc delete --force test_busybox1 test_busybox2
+
+ runc state test_busybox1
+ [ "$status" -ne 0 ]
+
+ runc state test_busybox2
+ [ "$status" -ne 0 ]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/ps.bats b/vendor/github.com/opencontainers/runc/tests/integration/ps.bats
new file mode 100644
index 00000000..7a200150
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/ps.bats
@@ -0,0 +1,59 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ teardown_busybox
+ setup_busybox
+}
+
+function teardown() {
+ teardown_busybox
+}
+
+@test "ps" {
+ # start busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ testcontainer test_busybox running
+
+ runc ps test_busybox
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ UID\ +PID\ +PPID\ +C\ +STIME\ +TTY\ +TIME\ +CMD+ ]]
+ [[ "${lines[1]}" == *"root"*[0-9]* ]]
+}
+
+@test "ps -f json" {
+ # start busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ testcontainer test_busybox running
+
+ runc ps -f json test_busybox
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ [0-9]+ ]]
+}
+
+@test "ps -e -x" {
+ # start busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ testcontainer test_busybox running
+
+ runc ps test_busybox -e -x
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ \ +PID\ +TTY\ +STAT\ +TIME\ +COMMAND+ ]]
+ [[ "${lines[1]}" =~ [0-9]+ ]]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/root.bats b/vendor/github.com/opencontainers/runc/tests/integration/root.bats
new file mode 100644
index 00000000..ee132917
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/root.bats
@@ -0,0 +1,54 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ teardown_running_container_inroot test_dotbox $HELLO_BUNDLE
+ teardown_busybox
+ setup_busybox
+}
+
+function teardown() {
+ teardown_running_container_inroot test_dotbox $HELLO_BUNDLE
+ teardown_busybox
+}
+
+@test "global --root" {
+ # run busybox detached using $HELLO_BUNDLE for state
+ ROOT=$HELLO_BUNDLE runc run -d --console-socket $CONSOLE_SOCKET test_dotbox
+ [ "$status" -eq 0 ]
+
+ # run busybox detached in default root
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state of the busyboxes are only in their respective root path
+ wait_for_container 15 1 test_busybox
+ wait_for_container_inroot 15 1 test_dotbox $HELLO_BUNDLE
+
+ runc state test_busybox
+ [ "$status" -eq 0 ]
+ [[ "${output}" == *"running"* ]]
+
+ ROOT=$HELLO_BUNDLE runc state test_dotbox
+ [ "$status" -eq 0 ]
+ [[ "${output}" == *"running"* ]]
+
+ ROOT=$HELLO_BUNDLE runc state test_busybox
+ [ "$status" -ne 0 ]
+
+ runc state test_dotbox
+ [ "$status" -ne 0 ]
+
+ runc kill test_busybox KILL
+ [ "$status" -eq 0 ]
+ retry 10 1 eval "__runc state test_busybox | grep -q 'stopped'"
+ runc delete test_busybox
+ [ "$status" -eq 0 ]
+
+ ROOT=$HELLO_BUNDLE runc kill test_dotbox KILL
+ [ "$status" -eq 0 ]
+ retry 10 1 eval "ROOT='$HELLO_BUNDLE' __runc state test_dotbox | grep -q 'stopped'"
+ ROOT=$HELLO_BUNDLE runc delete test_dotbox
+ [ "$status" -eq 0 ]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/spec.bats b/vendor/github.com/opencontainers/runc/tests/integration/spec.bats
new file mode 100644
index 00000000..a9ea8eb3
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/spec.bats
@@ -0,0 +1,95 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ # initial cleanup in case a prior test exited and did not cleanup
+ cd "$INTEGRATION_ROOT"
+ run rm -f -r "$HELLO_BUNDLE"
+
+ # setup hello-world for spec generation testing
+ run mkdir "$HELLO_BUNDLE"
+ run mkdir "$HELLO_BUNDLE"/rootfs
+ run tar -C "$HELLO_BUNDLE"/rootfs -xf "$HELLO_IMAGE"
+}
+
+function teardown() {
+ cd "$INTEGRATION_ROOT"
+ run rm -f -r "$HELLO_BUNDLE"
+}
+
+@test "spec generation cwd" {
+ cd "$HELLO_BUNDLE"
+ # note this test runs from the bundle not the integration root
+
+ # test that config.json does not exist after the above partial setup
+ [ ! -e config.json ]
+
+ # test generation of spec does not return an error
+ runc spec
+ [ "$status" -eq 0 ]
+
+ # test generation of spec created our config.json (spec)
+ [ -e config.json ]
+
+ # test existence of required args parameter in the generated config.json
+ run bash -c "grep -A2 'args' config.json | grep 'sh'"
+ [[ "${output}" == *"sh"* ]]
+
+ # change the default args parameter from sh to hello
+ sed -i 's;"sh";"/hello";' config.json
+
+ # ensure the generated spec works by running hello-world
+ runc run test_hello
+ [ "$status" -eq 0 ]
+}
+
+@test "spec generation --bundle" {
+ # note this test runs from the integration root not the bundle
+
+ # test that config.json does not exist after the above partial setup
+ [ ! -e "$HELLO_BUNDLE"/config.json ]
+
+ # test generation of spec does not return an error
+ runc spec --bundle "$HELLO_BUNDLE"
+ [ "$status" -eq 0 ]
+
+ # test generation of spec created our config.json (spec)
+ [ -e "$HELLO_BUNDLE"/config.json ]
+
+ # change the default args parameter from sh to hello
+ sed -i 's;"sh";"/hello";' "$HELLO_BUNDLE"/config.json
+
+ # ensure the generated spec works by running hello-world
+ runc run --bundle "$HELLO_BUNDLE" test_hello
+ [ "$status" -eq 0 ]
+}
+
+@test "spec validator" {
+ TESTDIR=$(pwd)
+ cd "$HELLO_BUNDLE"
+
+ run git clone https://github.com/opencontainers/runtime-spec.git src/runtime-spec
+ [ "$status" -eq 0 ]
+
+ SPEC_COMMIT=$(grep runtime-spec ${TESTDIR}/../../Godeps/Godeps.json -A 4 | grep Rev | cut -d":" -f 2 | tr -d ' "')
+ (
+ cd src/runtime-spec &&
+ run git reset --hard "${SPEC_COMMIT}"
+ )
+ [ "$status" -eq 0 ]
+ [ -e src/runtime-spec/schema/config-schema.json ]
+
+ run bash -c "GOPATH='$GOPATH' go get github.com/xeipuuv/gojsonschema"
+ [ "$status" -eq 0 ]
+
+ GOPATH="$GOPATH" go build src/runtime-spec/schema/validate.go
+ [ -e ./validate ]
+
+ runc spec
+ [ -e config.json ]
+
+ run ./validate src/runtime-spec/schema/config-schema.json config.json
+ [ "$status" -eq 0 ]
+ [[ "${lines[0]}" == *"The document is valid"* ]]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/start.bats b/vendor/github.com/opencontainers/runc/tests/integration/start.bats
new file mode 100644
index 00000000..cd33dee5
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/start.bats
@@ -0,0 +1,41 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ teardown_busybox
+ setup_busybox
+}
+
+function teardown() {
+ teardown_busybox
+}
+
+@test "runc start" {
+ runc create --console-socket $CONSOLE_SOCKET test_busybox1
+ [ "$status" -eq 0 ]
+
+ testcontainer test_busybox1 created
+
+ runc create --console-socket $CONSOLE_SOCKET test_busybox2
+ [ "$status" -eq 0 ]
+
+ testcontainer test_busybox2 created
+
+
+ # start container test_busybox1 and test_busybox2
+ runc start test_busybox1 test_busybox2
+ [ "$status" -eq 0 ]
+
+ testcontainer test_busybox1 running
+ testcontainer test_busybox2 running
+
+ # delete test_busybox1 and test_busybox2
+ runc delete --force test_busybox1 test_busybox2
+
+ runc state test_busybox1
+ [ "$status" -ne 0 ]
+
+ runc state test_busybox2
+ [ "$status" -ne 0 ]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/start_detached.bats b/vendor/github.com/opencontainers/runc/tests/integration/start_detached.bats
new file mode 100644
index 00000000..605fde22
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/start_detached.bats
@@ -0,0 +1,81 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ teardown_busybox
+ setup_busybox
+}
+
+function teardown() {
+ teardown_busybox
+}
+
+@test "runc run detached" {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ testcontainer test_busybox running
+}
+
+@test "runc run detached ({u,g}id != 0)" {
+ # replace "uid": 0 with "uid": 1000
+ # and do a similar thing for gid.
+ sed -i 's;"uid": 0;"uid": 1000;g' config.json
+ sed -i 's;"gid": 0;"gid": 100;g' config.json
+
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ testcontainer test_busybox running
+}
+
+@test "runc run detached --pid-file" {
+ # run busybox detached
+ runc run --pid-file pid.txt -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ testcontainer test_busybox running
+
+ # check pid.txt was generated
+ [ -e pid.txt ]
+
+ run cat pid.txt
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} == $(__runc state test_busybox | jq '.pid') ]]
+}
+
+@test "runc run detached --pid-file with new CWD" {
+ # create pid_file directory as the CWD
+ run mkdir pid_file
+ [ "$status" -eq 0 ]
+ run cd pid_file
+ [ "$status" -eq 0 ]
+
+ # run busybox detached
+ runc run --pid-file pid.txt -d -b $BUSYBOX_BUNDLE --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ testcontainer test_busybox running
+
+ # check pid.txt was generated
+ [ -e pid.txt ]
+
+ run cat pid.txt
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} == $(__runc state test_busybox | jq '.pid') ]]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/start_hello.bats b/vendor/github.com/opencontainers/runc/tests/integration/start_hello.bats
new file mode 100644
index 00000000..6de65e07
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/start_hello.bats
@@ -0,0 +1,61 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ teardown_hello
+ setup_hello
+}
+
+function teardown() {
+ teardown_hello
+}
+
+@test "runc run" {
+ # run hello-world
+ runc run test_hello
+ [ "$status" -eq 0 ]
+
+ # check expected output
+ [[ "${output}" == *"Hello"* ]]
+}
+
+@test "runc run ({u,g}id != 0)" {
+ # replace "uid": 0 with "uid": 1000
+ # and do a similar thing for gid.
+ sed -i 's;"uid": 0;"uid": 1000;g' config.json
+ sed -i 's;"gid": 0;"gid": 100;g' config.json
+
+ # run hello-world
+ runc run test_hello
+ [ "$status" -eq 0 ]
+
+ # check expected output
+ [[ "${output}" == *"Hello"* ]]
+}
+
+@test "runc run with rootfs set to ." {
+ cp config.json rootfs/.
+ rm config.json
+ cd rootfs
+ sed -i 's;"rootfs";".";' config.json
+
+ # run hello-world
+ runc run test_hello
+ [ "$status" -eq 0 ]
+ [[ "${output}" == *"Hello"* ]]
+}
+
+@test "runc run --pid-file" {
+ # run hello-world
+ runc run --pid-file pid.txt test_hello
+ [ "$status" -eq 0 ]
+ [[ "${output}" == *"Hello"* ]]
+
+ # check pid.txt was generated
+ [ -e pid.txt ]
+
+ run cat pid.txt
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ [0-9]+ ]]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/state.bats b/vendor/github.com/opencontainers/runc/tests/integration/state.bats
new file mode 100644
index 00000000..eed2eb3c
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/state.bats
@@ -0,0 +1,50 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ teardown_busybox
+ setup_busybox
+}
+
+function teardown() {
+ teardown_busybox
+}
+
+@test "state" {
+ runc state test_busybox
+ [ "$status" -ne 0 ]
+
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ testcontainer test_busybox running
+
+ # pause busybox
+ runc pause test_busybox
+ [ "$status" -eq 0 ]
+
+ # test state of busybox is paused
+ testcontainer test_busybox paused
+
+ # resume busybox
+ runc resume test_busybox
+ [ "$status" -eq 0 ]
+
+ # test state of busybox is back to running
+ testcontainer test_busybox running
+
+ runc kill test_busybox KILL
+ # wait for busybox to be in the destroyed state
+ retry 10 1 eval "__runc state test_busybox | grep -q 'stopped'"
+
+ # delete test_busybox
+ runc delete test_busybox
+
+ runc state test_busybox
+ [ "$status" -ne 0 ]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/testdata/hello-world.tar b/vendor/github.com/opencontainers/runc/tests/integration/testdata/hello-world.tar
new file mode 100644
index 00000000..aec830e2
Binary files /dev/null and b/vendor/github.com/opencontainers/runc/tests/integration/testdata/hello-world.tar differ
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/tty.bats b/vendor/github.com/opencontainers/runc/tests/integration/tty.bats
new file mode 100644
index 00000000..b9a1f108
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/tty.bats
@@ -0,0 +1,113 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function setup() {
+ teardown_busybox
+ setup_busybox
+}
+
+function teardown() {
+ teardown_busybox
+}
+
+@test "runc run [tty ptsname]" {
+ # Replace sh script with readlink.
+ sed -i 's|"sh"|"sh", "-c", "for file in /proc/self/fd/[012]; do readlink $file; done"|' config.json
+
+ # run busybox
+ runc run test_busybox
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ /dev/pts/+ ]]
+ [[ ${lines[1]} =~ /dev/pts/+ ]]
+ [[ ${lines[2]} =~ /dev/pts/+ ]]
+}
+
+@test "runc run [tty owner]" {
+ # Replace sh script with stat.
+ sed -i 's/"sh"/"sh", "-c", "stat -c %u:%g $(tty) | tr : \\\\\\\\n"/' config.json
+
+ # run busybox
+ runc run test_busybox
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ 0 ]]
+ # This is set by the default config.json (it corresponds to the standard tty group).
+ [[ ${lines[1]} =~ 5 ]]
+}
+
+@test "runc run [tty owner] ({u,g}id != 0)" {
+ # replace "uid": 0 with "uid": 1000
+ # and do a similar thing for gid.
+ sed -i 's;"uid": 0;"uid": 1000;g' config.json
+ sed -i 's;"gid": 0;"gid": 100;g' config.json
+
+ # Replace sh script with stat.
+ sed -i 's/"sh"/"sh", "-c", "stat -c %u:%g $(tty) | tr : \\\\\\\\n"/' config.json
+
+ # run busybox
+ runc run test_busybox
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ 1000 ]]
+ # This is set by the default config.json (it corresponds to the standard tty group).
+ [[ ${lines[1]} =~ 5 ]]
+}
+
+@test "runc exec [tty ptsname]" {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ # make sure we're running
+ testcontainer test_busybox running
+
+ # run the exec
+ runc exec test_busybox sh -c 'for file in /proc/self/fd/[012]; do readlink $file; done'
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ /dev/pts/+ ]]
+ [[ ${lines[1]} =~ /dev/pts/+ ]]
+ [[ ${lines[2]} =~ /dev/pts/+ ]]
+}
+
+@test "runc exec [tty owner]" {
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ # make sure we're running
+ testcontainer test_busybox running
+
+ # run the exec
+ runc exec test_busybox sh -c 'stat -c %u:%g $(tty) | tr : \\n'
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ 0 ]]
+ [[ ${lines[1]} =~ 5 ]]
+}
+
+@test "runc exec [tty owner] ({u,g}id != 0)" {
+ # replace "uid": 0 with "uid": 1000
+ # and do a similar thing for gid.
+ sed -i 's;"uid": 0;"uid": 1000;g' config.json
+ sed -i 's;"gid": 0;"gid": 100;g' config.json
+
+ # run busybox detached
+ runc run -d --console-socket $CONSOLE_SOCKET test_busybox
+ [ "$status" -eq 0 ]
+
+ # check state
+ wait_for_container 15 1 test_busybox
+
+ # make sure we're running
+ testcontainer test_busybox running
+
+ # run the exec
+ runc exec test_busybox sh -c 'stat -c %u:%g $(tty) | tr : \\n'
+ [ "$status" -eq 0 ]
+ [[ ${lines[0]} =~ 1000 ]]
+ [[ ${lines[1]} =~ 5 ]]
+}
diff --git a/vendor/github.com/opencontainers/runc/tests/integration/update.bats b/vendor/github.com/opencontainers/runc/tests/integration/update.bats
new file mode 100644
index 00000000..9e4c1102
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/tests/integration/update.bats
@@ -0,0 +1,243 @@
+#!/usr/bin/env bats
+
+load helpers
+
+function teardown() {
+ rm -f $BATS_TMPDIR/runc-update-integration-test.json
+ teardown_running_container test_update
+ teardown_running_container test_update_rt
+ teardown_busybox
+}
+
+function setup() {
+ teardown
+ setup_busybox
+
+ # Add cgroup path
+ sed -i 's/\("linux": {\)/\1\n "cgroupsPath": "\/runc-update-integration-test",/' ${BUSYBOX_BUNDLE}/config.json
+
+ # Set some initial known values
+ DATA=$(cat </ { print $5; exit }')
+ eval CGROUP_${g}="${base_path}/runc-update-integration-test"
+ done
+
+ # check that initial values were properly set
+ check_cgroup_value $CGROUP_BLKIO "blkio.weight" 1000
+ check_cgroup_value $CGROUP_CPU "cpu.cfs_period_us" 1000000
+ check_cgroup_value $CGROUP_CPU "cpu.cfs_quota_us" 500000
+ check_cgroup_value $CGROUP_CPU "cpu.shares" 100
+ check_cgroup_value $CGROUP_CPUSET "cpuset.cpus" 0
+ check_cgroup_value $CGROUP_MEMORY "memory.kmem.limit_in_bytes" 16777216
+ check_cgroup_value $CGROUP_MEMORY "memory.kmem.tcp.limit_in_bytes" 11534336
+ check_cgroup_value $CGROUP_MEMORY "memory.limit_in_bytes" 33554432
+ check_cgroup_value $CGROUP_MEMORY "memory.soft_limit_in_bytes" 25165824
+
+ # update blkio-weight
+ runc update test_update --blkio-weight 500
+ [ "$status" -eq 0 ]
+ check_cgroup_value $CGROUP_BLKIO "blkio.weight" 500
+
+ # update cpu-period
+ runc update test_update --cpu-period 900000
+ [ "$status" -eq 0 ]
+ check_cgroup_value $CGROUP_CPU "cpu.cfs_period_us" 900000
+
+ # update cpu-quota
+ runc update test_update --cpu-quota 600000
+ [ "$status" -eq 0 ]
+ check_cgroup_value $CGROUP_CPU "cpu.cfs_quota_us" 600000
+
+ # update cpu-shares
+ runc update test_update --cpu-share 200
+ [ "$status" -eq 0 ]
+ check_cgroup_value $CGROUP_CPU "cpu.shares" 200
+
+ # update cpuset if supported (i.e. we're running on a multicore cpu)
+ cpu_count=$(grep '^processor' /proc/cpuinfo | wc -l)
+ if [ $cpu_count -gt 1 ]; then
+ runc update test_update --cpuset-cpus "1"
+ [ "$status" -eq 0 ]
+ check_cgroup_value $CGROUP_CPUSET "cpuset.cpus" 1
+ fi
+
+ # update memory limit
+ runc update test_update --memory 67108864
+ [ "$status" -eq 0 ]
+ check_cgroup_value $CGROUP_MEMORY "memory.limit_in_bytes" 67108864
+
+ runc update test_update --memory 50M
+ [ "$status" -eq 0 ]
+ check_cgroup_value $CGROUP_MEMORY "memory.limit_in_bytes" 52428800
+
+
+ # update memory soft limit
+ runc update test_update --memory-reservation 33554432
+ [ "$status" -eq 0 ]
+ check_cgroup_value $CGROUP_MEMORY "memory.soft_limit_in_bytes" 33554432
+
+ # update memory swap (if available)
+ if [ -f "$CGROUP_MEMORY/memory.memsw.limit_in_bytes" ]; then
+ runc update test_update --memory-swap 96468992
+ [ "$status" -eq 0 ]
+ check_cgroup_value $CGROUP_MEMORY "memory.memsw.limit_in_bytes" 96468992
+ fi
+
+ # update kernel memory limit
+ runc update test_update --kernel-memory 50331648
+ [ "$status" -eq 0 ]
+ check_cgroup_value $CGROUP_MEMORY "memory.kmem.limit_in_bytes" 50331648
+
+ # update kernel memory tcp limit
+ runc update test_update --kernel-memory-tcp 41943040
+ [ "$status" -eq 0 ]
+ check_cgroup_value $CGROUP_MEMORY "memory.kmem.tcp.limit_in_bytes" 41943040
+
+ # Revert to the test initial value via json on stding
+ runc update -r - test_update < $BATS_TMPDIR/runc-update-integration-test.json
+
+ runc update -r $BATS_TMPDIR/runc-update-integration-test.json test_update
+ [ "$status" -eq 0 ]
+ check_cgroup_value $CGROUP_BLKIO "blkio.weight" 1000
+ check_cgroup_value $CGROUP_CPU "cpu.cfs_period_us" 1000000
+ check_cgroup_value $CGROUP_CPU "cpu.cfs_quota_us" 500000
+ check_cgroup_value $CGROUP_CPU "cpu.shares" 100
+ check_cgroup_value $CGROUP_CPUSET "cpuset.cpus" 0
+ check_cgroup_value $CGROUP_MEMORY "memory.kmem.limit_in_bytes" 16777216
+ check_cgroup_value $CGROUP_MEMORY "memory.kmem.tcp.limit_in_bytes" 11534336
+ check_cgroup_value $CGROUP_MEMORY "memory.limit_in_bytes" 33554432
+ check_cgroup_value $CGROUP_MEMORY "memory.soft_limit_in_bytes" 25165824
+}
+
+@test "update rt period and runtime" {
+ requires cgroups_rt
+
+ # run a detached busybox
+ runc run -d --console-socket $CONSOLE_SOCKET test_update_rt
+ [ "$status" -eq 0 ]
+ wait_for_container 15 1 test_update_rt
+
+ # get the cgroup paths
+ eval CGROUP_CPU="${CGROUP_CPU_BASE_PATH}/runc-update-integration-test"
+
+ runc update -r - test_update_rt <out 2>err
-rc=$?
-if [[ $rc != 0 || -s err ]]; then
- echo Error while running start
- echo Exit code: $rc
- echo Error: $(cat err)
- echo Output: $(cat out)
- exit 1
-fi
-if [[ "$(cat out)" != "hi" ]]; then
- echo -e Incorrect output: $(cat out)\nExpected: hi
- exit 1
-fi
-echo "PASS: runc start"
-
-# Test exec
-################################################################
-set -ex
-rm config.json && $RUNC spec # reset things
-sed -i 's/"sh"/"sleep","6"/' config.json
-$RUNC start -d --console /dev/ptmx c1 >out 2>&1
-rc=$?
-if [[ $rc != 0 || -s out ]]; then
- echo Error while running start
- echo Exit code: $rc
- echo Output: $(cat out)
- exit 1
-fi
-sleep 1
-$RUNC exec c1 echo from exec >out 2>err
-rc=$?
-if [[ $rc != 0 || -s err ]]; then
- echo Error while running exec
- echo Exit code: $rc
- echo Error: $(cat err)
- echo Output: $(cat out)
- exit 1
-fi
-$RUNC kill c1
-rm -rf /run/opencontainer/containers/c1
-echo "PASS: runc exec"
-
-# Test pause/resume
-################################################################
-rm config.json && $RUNC spec # reset things
-sed -i 's/"sh"/"sleep","6"/' config.json
-$RUNC start -d --console /dev/ptmx c1 >out 2>&1
-rc=$?
-if [[ $rc != 0 || -s out ]]; then
- echo Error while running start
- echo Exit code: $rc
- echo Output: $(cat out)
- exit 1
-fi
-sleep 1
-$RUNC pause c1 >out 2>&1
-rc=$?
-if [[ $rc != 0 || -s out ]]; then
- echo Error while running pause
- echo Exit code: $rc
- echo Output: $(cat out)
- exit 1
-fi
-$RUNC resume c1 >out 2>&1
-rc=$?
-if [[ $? != 0 || -s out ]]; then
- echo Error while running pause
- echo Exit code: $rc
- echo Output: $(cat out)
- exit 1
-fi
-
-$RUNC kill c1
-rm -rf /run/opencontainer/containers/c1
-echo "PASS: runc pause/resume"
-
-# give it a sec before we erase the dir
-sleep 5
-cd ..
-rm -rf $DIR
diff --git a/vendor/github.com/opencontainers/runc/tty.go b/vendor/github.com/opencontainers/runc/tty.go
index 80c65515..0baed5a4 100644
--- a/vendor/github.com/opencontainers/runc/tty.go
+++ b/vendor/github.com/opencontainers/runc/tty.go
@@ -7,15 +7,31 @@ import (
"io"
"os"
"sync"
+ "syscall"
"github.com/docker/docker/pkg/term"
"github.com/opencontainers/runc/libcontainer"
+ "github.com/opencontainers/runc/libcontainer/utils"
)
+type tty struct {
+ console libcontainer.Console
+ state *term.State
+ closers []io.Closer
+ postStart []io.Closer
+ wg sync.WaitGroup
+}
+
+func (t *tty) copyIO(w io.Writer, r io.ReadCloser) {
+ defer t.wg.Done()
+ io.Copy(w, r)
+ r.Close()
+}
+
// setup standard pipes so that the TTY of the calling runc process
// is not inherited by the container.
-func createStdioPipes(p *libcontainer.Process, rootuid int) (*tty, error) {
- i, err := p.InitializeIO(rootuid)
+func createStdioPipes(p *libcontainer.Process, rootuid, rootgid int) (*tty, error) {
+ i, err := p.InitializeIO(rootuid, rootgid)
if err != nil {
return nil, err
}
@@ -46,45 +62,53 @@ func createStdioPipes(p *libcontainer.Process, rootuid int) (*tty, error) {
return t, nil
}
-func (t *tty) copyIO(w io.Writer, r io.ReadCloser) {
- defer t.wg.Done()
- io.Copy(w, r)
- r.Close()
-}
-
-func createTty(p *libcontainer.Process, rootuid int, consolePath string) (*tty, error) {
- if consolePath != "" {
- if err := p.ConsoleFromPath(consolePath); err != nil {
- return nil, err
+func dupStdio(process *libcontainer.Process, rootuid, rootgid int) error {
+ process.Stdin = os.Stdin
+ process.Stdout = os.Stdout
+ process.Stderr = os.Stderr
+ for _, fd := range []uintptr{
+ os.Stdin.Fd(),
+ os.Stdout.Fd(),
+ os.Stderr.Fd(),
+ } {
+ if err := syscall.Fchown(int(fd), rootuid, rootgid); err != nil {
+ return err
}
- return &tty{}, nil
}
- console, err := p.NewConsole(rootuid)
- if err != nil {
- return nil, err
- }
- go io.Copy(console, os.Stdin)
- go io.Copy(os.Stdout, console)
-
- state, err := term.SetRawTerminal(os.Stdin.Fd())
- if err != nil {
- return nil, fmt.Errorf("failed to set the terminal from the stdin: %v", err)
- }
- return &tty{
- console: console,
- state: state,
- closers: []io.Closer{
- console,
- },
- }, nil
+ return nil
}
-type tty struct {
- console libcontainer.Console
- state *term.State
- closers []io.Closer
- postStart []io.Closer
- wg sync.WaitGroup
+func (t *tty) recvtty(process *libcontainer.Process, detach bool) error {
+ console, err := process.GetConsole()
+ if err != nil {
+ return err
+ }
+
+ if !detach {
+ go io.Copy(console, os.Stdin)
+ t.wg.Add(1)
+ go t.copyIO(os.Stdout, console)
+
+ state, err := term.SetRawTerminal(os.Stdin.Fd())
+ if err != nil {
+ return fmt.Errorf("failed to set the terminal from the stdin: %v", err)
+ }
+ t.state = state
+ }
+
+ t.console = console
+ t.closers = []io.Closer{console}
+ return nil
+}
+
+func (t *tty) sendtty(socket *os.File, ti *libcontainer.TerminalInfo) error {
+ if t.console == nil {
+ return fmt.Errorf("tty.console not set")
+ }
+
+ // Create a fake file to contain the terminal info.
+ console := os.NewFile(t.console.File().Fd(), ti.String())
+ return utils.SendFd(socket, console)
}
// ClosePostStart closes any fds that are provided to the container and dup2'd
@@ -122,5 +146,5 @@ func (t *tty) resize() error {
if err != nil {
return err
}
- return term.SetWinsize(t.console.Fd(), ws)
+ return term.SetWinsize(t.console.File().Fd(), ws)
}
diff --git a/vendor/github.com/opencontainers/runc/update.go b/vendor/github.com/opencontainers/runc/update.go
new file mode 100644
index 00000000..cecd9986
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/update.go
@@ -0,0 +1,229 @@
+// +build linux
+
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+ "strconv"
+
+ "github.com/docker/go-units"
+ "github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/urfave/cli"
+)
+
+func u64Ptr(i uint64) *uint64 { return &i }
+func u16Ptr(i uint16) *uint16 { return &i }
+
+var updateCommand = cli.Command{
+ Name: "update",
+ Usage: "update container resource constraints",
+ ArgsUsage: ``,
+ Flags: []cli.Flag{
+ cli.StringFlag{
+ Name: "resources, r",
+ Value: "",
+ Usage: `path to the file containing the resources to update or '-' to read from the standard input
+
+The accepted format is as follow (unchanged values can be omitted):
+
+{
+ "memory": {
+ "limit": 0,
+ "reservation": 0,
+ "swap": 0,
+ "kernel": 0,
+ "kernelTCP": 0
+ },
+ "cpu": {
+ "shares": 0,
+ "quota": 0,
+ "period": 0,
+ "realtimeRuntime": 0,
+ "realtimePeriod": 0,
+ "cpus": "",
+ "mems": ""
+ },
+ "blockIO": {
+ "blkioWeight": 0
+ }
+}
+
+Note: if data is to be read from a file or the standard input, all
+other options are ignored.
+`,
+ },
+
+ cli.IntFlag{
+ Name: "blkio-weight",
+ Usage: "Specifies per cgroup weight, range is from 10 to 1000",
+ },
+ cli.StringFlag{
+ Name: "cpu-period",
+ Usage: "CPU CFS period to be used for hardcapping (in usecs). 0 to use system default",
+ },
+ cli.StringFlag{
+ Name: "cpu-quota",
+ Usage: "CPU CFS hardcap limit (in usecs). Allowed cpu time in a given period",
+ },
+ cli.StringFlag{
+ Name: "cpu-share",
+ Usage: "CPU shares (relative weight vs. other containers)",
+ },
+ cli.StringFlag{
+ Name: "cpu-rt-period",
+ Usage: "CPU realtime period to be used for hardcapping (in usecs). 0 to use system default",
+ },
+ cli.StringFlag{
+ Name: "cpu-rt-runtime",
+ Usage: "CPU realtime hardcap limit (in usecs). Allowed cpu time in a given period",
+ },
+ cli.StringFlag{
+ Name: "cpuset-cpus",
+ Usage: "CPU(s) to use",
+ },
+ cli.StringFlag{
+ Name: "cpuset-mems",
+ Usage: "Memory node(s) to use",
+ },
+ cli.StringFlag{
+ Name: "kernel-memory",
+ Usage: "Kernel memory limit (in bytes)",
+ },
+ cli.StringFlag{
+ Name: "kernel-memory-tcp",
+ Usage: "Kernel memory limit (in bytes) for tcp buffer",
+ },
+ cli.StringFlag{
+ Name: "memory",
+ Usage: "Memory limit (in bytes)",
+ },
+ cli.StringFlag{
+ Name: "memory-reservation",
+ Usage: "Memory reservation or soft_limit (in bytes)",
+ },
+ cli.StringFlag{
+ Name: "memory-swap",
+ Usage: "Total memory usage (memory + swap); set '-1' to enable unlimited swap",
+ },
+ },
+ Action: func(context *cli.Context) error {
+ if err := checkArgs(context, 1, exactArgs); err != nil {
+ return err
+ }
+ container, err := getContainer(context)
+ if err != nil {
+ return err
+ }
+
+ r := specs.LinuxResources{
+ Memory: &specs.LinuxMemory{
+ Limit: u64Ptr(0),
+ Reservation: u64Ptr(0),
+ Swap: u64Ptr(0),
+ Kernel: u64Ptr(0),
+ KernelTCP: u64Ptr(0),
+ },
+ CPU: &specs.LinuxCPU{
+ Shares: u64Ptr(0),
+ Quota: u64Ptr(0),
+ Period: u64Ptr(0),
+ RealtimeRuntime: u64Ptr(0),
+ RealtimePeriod: u64Ptr(0),
+ Cpus: sPtr(""),
+ Mems: sPtr(""),
+ },
+ BlockIO: &specs.LinuxBlockIO{
+ Weight: u16Ptr(0),
+ },
+ }
+
+ config := container.Config()
+
+ if in := context.String("resources"); in != "" {
+ var (
+ f *os.File
+ err error
+ )
+ switch in {
+ case "-":
+ f = os.Stdin
+ default:
+ f, err = os.Open(in)
+ if err != nil {
+ return err
+ }
+ }
+ err = json.NewDecoder(f).Decode(&r)
+ if err != nil {
+ return err
+ }
+ } else {
+ if val := context.Int("blkio-weight"); val != 0 {
+ r.BlockIO.Weight = u16Ptr(uint16(val))
+ }
+ if val := context.String("cpuset-cpus"); val != "" {
+ r.CPU.Cpus = &val
+ }
+ if val := context.String("cpuset-mems"); val != "" {
+ r.CPU.Mems = &val
+ }
+
+ for _, pair := range []struct {
+ opt string
+ dest *uint64
+ }{
+
+ {"cpu-period", r.CPU.Period},
+ {"cpu-quota", r.CPU.Quota},
+ {"cpu-rt-period", r.CPU.RealtimePeriod},
+ {"cpu-rt-runtime", r.CPU.RealtimeRuntime},
+ {"cpu-share", r.CPU.Shares},
+ } {
+ if val := context.String(pair.opt); val != "" {
+ var err error
+ *pair.dest, err = strconv.ParseUint(val, 10, 64)
+ if err != nil {
+ return fmt.Errorf("invalid value for %s: %s", pair.opt, err)
+ }
+ }
+ }
+ for _, pair := range []struct {
+ opt string
+ dest *uint64
+ }{
+ {"kernel-memory", r.Memory.Kernel},
+ {"kernel-memory-tcp", r.Memory.KernelTCP},
+ {"memory", r.Memory.Limit},
+ {"memory-reservation", r.Memory.Reservation},
+ {"memory-swap", r.Memory.Swap},
+ } {
+ if val := context.String(pair.opt); val != "" {
+ v, err := units.RAMInBytes(val)
+ if err != nil {
+ return fmt.Errorf("invalid value for %s: %s", pair.opt, err)
+ }
+ *pair.dest = uint64(v)
+ }
+ }
+ }
+
+ // Update the value
+ config.Cgroups.Resources.BlkioWeight = *r.BlockIO.Weight
+ config.Cgroups.Resources.CpuPeriod = int64(*r.CPU.Period)
+ config.Cgroups.Resources.CpuQuota = int64(*r.CPU.Quota)
+ config.Cgroups.Resources.CpuShares = int64(*r.CPU.Shares)
+ config.Cgroups.Resources.CpuRtPeriod = int64(*r.CPU.RealtimePeriod)
+ config.Cgroups.Resources.CpuRtRuntime = int64(*r.CPU.RealtimeRuntime)
+ config.Cgroups.Resources.CpusetCpus = *r.CPU.Cpus
+ config.Cgroups.Resources.CpusetMems = *r.CPU.Mems
+ config.Cgroups.Resources.KernelMemory = int64(*r.Memory.Kernel)
+ config.Cgroups.Resources.KernelMemoryTCP = int64(*r.Memory.KernelTCP)
+ config.Cgroups.Resources.Memory = int64(*r.Memory.Limit)
+ config.Cgroups.Resources.MemoryReservation = int64(*r.Memory.Reservation)
+ config.Cgroups.Resources.MemorySwap = int64(*r.Memory.Swap)
+
+ return container.Set(config)
+ },
+}
diff --git a/vendor/github.com/opencontainers/runc/utils.go b/vendor/github.com/opencontainers/runc/utils.go
index e34d6558..3c3785b9 100644
--- a/vendor/github.com/opencontainers/runc/utils.go
+++ b/vendor/github.com/opencontainers/runc/utils.go
@@ -1,59 +1,45 @@
-// +build linux
-
package main
import (
- "errors"
"fmt"
"os"
"path/filepath"
- "syscall"
"github.com/Sirupsen/logrus"
- "github.com/codegangsta/cli"
- "github.com/opencontainers/runc/libcontainer"
- "github.com/opencontainers/runc/libcontainer/cgroups/systemd"
- "github.com/opencontainers/runc/libcontainer/specconv"
"github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/urfave/cli"
)
-var errEmptyID = errors.New("container id cannot be empty")
+const (
+ exactArgs = iota
+ minArgs
+ maxArgs
+)
-var container libcontainer.Container
-
-// loadFactory returns the configured factory instance for execing containers.
-func loadFactory(context *cli.Context) (libcontainer.Factory, error) {
- root := context.GlobalString("root")
- abs, err := filepath.Abs(root)
- if err != nil {
- return nil, err
- }
- cgroupManager := libcontainer.Cgroupfs
- if context.GlobalBool("systemd-cgroup") {
- if systemd.UseSystemd() {
- cgroupManager = libcontainer.SystemdCgroups
- } else {
- return nil, fmt.Errorf("systemd cgroup flag passed, but systemd support for managing cgroups is not available.")
+func checkArgs(context *cli.Context, expected, checkType int) error {
+ var err error
+ cmdName := context.Command.Name
+ switch checkType {
+ case exactArgs:
+ if context.NArg() != expected {
+ err = fmt.Errorf("%s: %q requires exactly %d argument(s)", os.Args[0], cmdName, expected)
+ }
+ case minArgs:
+ if context.NArg() < expected {
+ err = fmt.Errorf("%s: %q requires a minimum of %d argument(s)", os.Args[0], cmdName, expected)
+ }
+ case maxArgs:
+ if context.NArg() > expected {
+ err = fmt.Errorf("%s: %q requires a maximum of %d argument(s)", os.Args[0], cmdName, expected)
}
}
- return libcontainer.New(abs, cgroupManager, func(l *libcontainer.LinuxFactory) error {
- l.CriuPath = context.GlobalString("criu")
- return nil
- })
-}
-// getContainer returns the specified container instance by loading it from state
-// with the default factory.
-func getContainer(context *cli.Context) (libcontainer.Container, error) {
- id := context.Args().First()
- if id == "" {
- return nil, errEmptyID
- }
- factory, err := loadFactory(context)
if err != nil {
- return nil, err
+ fmt.Printf("Incorrect Usage.\n\n")
+ cli.ShowCommandHelp(context, cmdName)
+ return err
}
- return factory.Load(id)
+ return nil
}
// fatal prints the error's details if it is a libcontainer specific error type
@@ -65,223 +51,39 @@ func fatal(err error) {
os.Exit(1)
}
-func fatalf(t string, v ...interface{}) {
- fatal(fmt.Errorf(t, v...))
-}
-
-func getDefaultImagePath(context *cli.Context) string {
- cwd, err := os.Getwd()
- if err != nil {
- panic(err)
- }
- return filepath.Join(cwd, "checkpoint")
-}
-
-// newProcess returns a new libcontainer Process with the arguments from the
-// spec and stdio from the current process.
-func newProcess(p specs.Process) (*libcontainer.Process, error) {
- lp := &libcontainer.Process{
- Args: p.Args,
- Env: p.Env,
- // TODO: fix libcontainer's API to better support uid/gid in a typesafe way.
- User: fmt.Sprintf("%d:%d", p.User.UID, p.User.GID),
- Cwd: p.Cwd,
- Capabilities: p.Capabilities,
- Label: p.SelinuxLabel,
- NoNewPrivileges: &p.NoNewPrivileges,
- AppArmorProfile: p.ApparmorProfile,
- }
- for _, rlimit := range p.Rlimits {
- rl, err := createLibContainerRlimit(rlimit)
- if err != nil {
+// setupSpec performs initial setup based on the cli.Context for the container
+func setupSpec(context *cli.Context) (*specs.Spec, error) {
+ bundle := context.String("bundle")
+ if bundle != "" {
+ if err := os.Chdir(bundle); err != nil {
return nil, err
}
- lp.Rlimits = append(lp.Rlimits, rl)
}
- return lp, nil
-}
-
-func dupStdio(process *libcontainer.Process, rootuid int) error {
- process.Stdin = os.Stdin
- process.Stdout = os.Stdout
- process.Stderr = os.Stderr
- for _, fd := range []uintptr{
- os.Stdin.Fd(),
- os.Stdout.Fd(),
- os.Stderr.Fd(),
- } {
- if err := syscall.Fchown(int(fd), rootuid, rootuid); err != nil {
- return err
- }
- }
- return nil
-}
-
-// If systemd is supporting sd_notify protocol, this function will add support
-// for sd_notify protocol from within the container.
-func setupSdNotify(spec *specs.Spec, notifySocket string) {
- spec.Mounts = append(spec.Mounts, specs.Mount{Destination: notifySocket, Type: "bind", Source: notifySocket, Options: []string{"bind"}})
- spec.Process.Env = append(spec.Process.Env, fmt.Sprintf("NOTIFY_SOCKET=%s", notifySocket))
-}
-
-func destroy(container libcontainer.Container) {
- if err := container.Destroy(); err != nil {
- logrus.Error(err)
- }
-}
-
-// setupIO sets the proper IO on the process depending on the configuration
-// If there is a nil error then there must be a non nil tty returned
-func setupIO(process *libcontainer.Process, rootuid int, console string, createTTY, detach bool) (*tty, error) {
- // detach and createTty will not work unless a console path is passed
- // so error out here before changing any terminal settings
- if createTTY && detach && console == "" {
- return nil, fmt.Errorf("cannot allocate tty if runc will detach")
- }
- if createTTY {
- return createTty(process, rootuid, console)
- }
- if detach {
- if err := dupStdio(process, rootuid); err != nil {
- return nil, err
- }
- return &tty{}, nil
- }
- return createStdioPipes(process, rootuid)
-}
-
-// createPidFile creates a file with the processes pid inside it atomically
-// it creates a temp file with the paths filename + '.' infront of it
-// then renames the file
-func createPidFile(path string, process *libcontainer.Process) error {
- pid, err := process.Pid()
- if err != nil {
- return err
- }
- var (
- tmpDir = filepath.Dir(path)
- tmpName = filepath.Join(tmpDir, fmt.Sprintf(".%s", filepath.Base(path)))
- )
- f, err := os.OpenFile(tmpName, os.O_RDWR|os.O_CREATE|os.O_EXCL|os.O_SYNC, 0666)
- if err != nil {
- return err
- }
- _, err = fmt.Fprintf(f, "%d", pid)
- f.Close()
- if err != nil {
- return err
- }
- return os.Rename(tmpName, path)
-}
-
-func createContainer(context *cli.Context, id string, spec *specs.Spec) (libcontainer.Container, error) {
- config, err := specconv.CreateLibcontainerConfig(&specconv.CreateOpts{
- CgroupName: id,
- UseSystemdCgroup: context.GlobalBool("systemd-cgroup"),
- NoPivotRoot: context.Bool("no-pivot"),
- Spec: spec,
- })
+ spec, err := loadSpec(specConfig)
if err != nil {
return nil, err
}
+ notifySocket := os.Getenv("NOTIFY_SOCKET")
+ if notifySocket != "" {
+ setupSdNotify(spec, notifySocket)
+ }
+ if os.Geteuid() != 0 {
+ return nil, fmt.Errorf("runc should be run as root")
+ }
+ return spec, nil
+}
- if _, err := os.Stat(config.Rootfs); err != nil {
- if os.IsNotExist(err) {
- return nil, fmt.Errorf("rootfs (%q) does not exist", config.Rootfs)
- }
- return nil, err
+func revisePidFile(context *cli.Context) error {
+ pidFile := context.String("pid-file")
+ if pidFile == "" {
+ return nil
}
- factory, err := loadFactory(context)
+ // convert pid-file to an absolute path so we can write to the right
+ // file after chdir to bundle
+ pidFile, err := filepath.Abs(pidFile)
if err != nil {
- return nil, err
+ return err
}
- return factory.Create(id, config)
-}
-
-type runner struct {
- enableSubreaper bool
- shouldDestroy bool
- detach bool
- listenFDs []*os.File
- pidFile string
- console string
- container libcontainer.Container
-}
-
-func (r *runner) run(config *specs.Process) (int, error) {
- process, err := newProcess(*config)
- if err != nil {
- r.destroy()
- return -1, err
- }
- if len(r.listenFDs) > 0 {
- process.Env = append(process.Env, fmt.Sprintf("LISTEN_FDS=%d", len(r.listenFDs)), "LISTEN_PID=1")
- process.ExtraFiles = append(process.ExtraFiles, r.listenFDs...)
- }
- rootuid, err := r.container.Config().HostUID()
- if err != nil {
- r.destroy()
- return -1, err
- }
- tty, err := setupIO(process, rootuid, r.console, config.Terminal, r.detach)
- if err != nil {
- r.destroy()
- return -1, err
- }
- handler := newSignalHandler(tty, r.enableSubreaper)
- if err := r.container.Start(process); err != nil {
- r.destroy()
- tty.Close()
- return -1, err
- }
- if err := tty.ClosePostStart(); err != nil {
- r.terminate(process)
- r.destroy()
- tty.Close()
- return -1, err
- }
- if r.pidFile != "" {
- if err := createPidFile(r.pidFile, process); err != nil {
- r.terminate(process)
- r.destroy()
- tty.Close()
- return -1, err
- }
- }
- if r.detach {
- tty.Close()
- return 0, nil
- }
- status, err := handler.forward(process)
- if err != nil {
- r.terminate(process)
- }
- r.destroy()
- tty.Close()
- return status, err
-}
-
-func (r *runner) destroy() {
- if r.shouldDestroy {
- destroy(r.container)
- }
-}
-
-func (r *runner) terminate(p *libcontainer.Process) {
- p.Signal(syscall.SIGKILL)
- p.Wait()
-}
-
-func validateProcessSpec(spec *specs.Process) error {
- if spec.Cwd == "" {
- return fmt.Errorf("Cwd property must not be empty")
- }
- if !filepath.IsAbs(spec.Cwd) {
- return fmt.Errorf("Cwd must be an absolute path")
- }
- if len(spec.Args) == 0 {
- return fmt.Errorf("args must not be empty")
- }
- return nil
+ return context.Set("pid-file", pidFile)
}
diff --git a/vendor/github.com/opencontainers/runc/utils_linux.go b/vendor/github.com/opencontainers/runc/utils_linux.go
new file mode 100644
index 00000000..867c2d7a
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/utils_linux.go
@@ -0,0 +1,359 @@
+// +build linux
+
+package main
+
+import (
+ "errors"
+ "fmt"
+ "net"
+ "os"
+ "path/filepath"
+ "strconv"
+ "syscall"
+
+ "github.com/Sirupsen/logrus"
+ "github.com/coreos/go-systemd/activation"
+ "github.com/opencontainers/runc/libcontainer"
+ "github.com/opencontainers/runc/libcontainer/cgroups/systemd"
+ "github.com/opencontainers/runc/libcontainer/specconv"
+ "github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/urfave/cli"
+)
+
+var errEmptyID = errors.New("container id cannot be empty")
+
+var container libcontainer.Container
+
+// loadFactory returns the configured factory instance for execing containers.
+func loadFactory(context *cli.Context) (libcontainer.Factory, error) {
+ root := context.GlobalString("root")
+ abs, err := filepath.Abs(root)
+ if err != nil {
+ return nil, err
+ }
+ cgroupManager := libcontainer.Cgroupfs
+ if context.GlobalBool("systemd-cgroup") {
+ if systemd.UseSystemd() {
+ cgroupManager = libcontainer.SystemdCgroups
+ } else {
+ return nil, fmt.Errorf("systemd cgroup flag passed, but systemd support for managing cgroups is not available")
+ }
+ }
+ return libcontainer.New(abs, cgroupManager, libcontainer.CriuPath(context.GlobalString("criu")))
+}
+
+// getContainer returns the specified container instance by loading it from state
+// with the default factory.
+func getContainer(context *cli.Context) (libcontainer.Container, error) {
+ id := context.Args().First()
+ if id == "" {
+ return nil, errEmptyID
+ }
+ factory, err := loadFactory(context)
+ if err != nil {
+ return nil, err
+ }
+ return factory.Load(id)
+}
+
+func fatalf(t string, v ...interface{}) {
+ fatal(fmt.Errorf(t, v...))
+}
+
+func getDefaultImagePath(context *cli.Context) string {
+ cwd, err := os.Getwd()
+ if err != nil {
+ panic(err)
+ }
+ return filepath.Join(cwd, "checkpoint")
+}
+
+// newProcess returns a new libcontainer Process with the arguments from the
+// spec and stdio from the current process.
+func newProcess(p specs.Process) (*libcontainer.Process, error) {
+ lp := &libcontainer.Process{
+ Args: p.Args,
+ Env: p.Env,
+ // TODO: fix libcontainer's API to better support uid/gid in a typesafe way.
+ User: fmt.Sprintf("%d:%d", p.User.UID, p.User.GID),
+ Cwd: p.Cwd,
+ Capabilities: p.Capabilities,
+ Label: p.SelinuxLabel,
+ NoNewPrivileges: &p.NoNewPrivileges,
+ AppArmorProfile: p.ApparmorProfile,
+ }
+ for _, gid := range p.User.AdditionalGids {
+ lp.AdditionalGroups = append(lp.AdditionalGroups, strconv.FormatUint(uint64(gid), 10))
+ }
+ for _, rlimit := range p.Rlimits {
+ rl, err := createLibContainerRlimit(rlimit)
+ if err != nil {
+ return nil, err
+ }
+ lp.Rlimits = append(lp.Rlimits, rl)
+ }
+ return lp, nil
+}
+
+// If systemd is supporting sd_notify protocol, this function will add support
+// for sd_notify protocol from within the container.
+func setupSdNotify(spec *specs.Spec, notifySocket string) {
+ spec.Mounts = append(spec.Mounts, specs.Mount{Destination: notifySocket, Type: "bind", Source: notifySocket, Options: []string{"bind"}})
+ spec.Process.Env = append(spec.Process.Env, fmt.Sprintf("NOTIFY_SOCKET=%s", notifySocket))
+}
+
+func destroy(container libcontainer.Container) {
+ if err := container.Destroy(); err != nil {
+ logrus.Error(err)
+ }
+}
+
+// setupIO modifies the given process config according to the options.
+func setupIO(process *libcontainer.Process, rootuid, rootgid int, createTTY, detach bool) (*tty, error) {
+ // This is entirely handled by recvtty.
+ if createTTY {
+ process.Stdin = nil
+ process.Stdout = nil
+ process.Stderr = nil
+ return &tty{}, nil
+ }
+
+ // When we detach, we just dup over stdio and call it a day. There's no
+ // requirement that we set up anything nice for our caller or the
+ // container.
+ if detach {
+ if err := dupStdio(process, rootuid, rootgid); err != nil {
+ return nil, err
+ }
+ return &tty{}, nil
+ }
+
+ // XXX: This doesn't sit right with me. It's ugly.
+ return createStdioPipes(process, rootuid, rootgid)
+}
+
+// createPidFile creates a file with the processes pid inside it atomically
+// it creates a temp file with the paths filename + '.' infront of it
+// then renames the file
+func createPidFile(path string, process *libcontainer.Process) error {
+ pid, err := process.Pid()
+ if err != nil {
+ return err
+ }
+ var (
+ tmpDir = filepath.Dir(path)
+ tmpName = filepath.Join(tmpDir, fmt.Sprintf(".%s", filepath.Base(path)))
+ )
+ f, err := os.OpenFile(tmpName, os.O_RDWR|os.O_CREATE|os.O_EXCL|os.O_SYNC, 0666)
+ if err != nil {
+ return err
+ }
+ _, err = fmt.Fprintf(f, "%d", pid)
+ f.Close()
+ if err != nil {
+ return err
+ }
+ return os.Rename(tmpName, path)
+}
+
+func createContainer(context *cli.Context, id string, spec *specs.Spec) (libcontainer.Container, error) {
+ config, err := specconv.CreateLibcontainerConfig(&specconv.CreateOpts{
+ CgroupName: id,
+ UseSystemdCgroup: context.GlobalBool("systemd-cgroup"),
+ NoPivotRoot: context.Bool("no-pivot"),
+ NoNewKeyring: context.Bool("no-new-keyring"),
+ Spec: spec,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ factory, err := loadFactory(context)
+ if err != nil {
+ return nil, err
+ }
+ return factory.Create(id, config)
+}
+
+type runner struct {
+ enableSubreaper bool
+ shouldDestroy bool
+ detach bool
+ listenFDs []*os.File
+ pidFile string
+ consoleSocket string
+ container libcontainer.Container
+ create bool
+}
+
+func (r *runner) terminalinfo() *libcontainer.TerminalInfo {
+ return libcontainer.NewTerminalInfo(r.container.ID())
+}
+
+func (r *runner) run(config *specs.Process) (int, error) {
+ process, err := newProcess(*config)
+ if err != nil {
+ r.destroy()
+ return -1, err
+ }
+ if len(r.listenFDs) > 0 {
+ process.Env = append(process.Env, fmt.Sprintf("LISTEN_FDS=%d", len(r.listenFDs)), "LISTEN_PID=1")
+ process.ExtraFiles = append(process.ExtraFiles, r.listenFDs...)
+ }
+
+ rootuid, err := r.container.Config().HostUID()
+ if err != nil {
+ r.destroy()
+ return -1, err
+ }
+
+ rootgid, err := r.container.Config().HostGID()
+ if err != nil {
+ r.destroy()
+ return -1, err
+ }
+
+ detach := r.detach || r.create
+
+ // Check command-line for sanity.
+ if detach && config.Terminal && r.consoleSocket == "" {
+ r.destroy()
+ return -1, fmt.Errorf("cannot allocate tty if runc will detach without setting console socket")
+ }
+ // XXX: Should we change this?
+ if (!detach || !config.Terminal) && r.consoleSocket != "" {
+ r.destroy()
+ return -1, fmt.Errorf("cannot use console socket if runc will not detach or allocate tty")
+ }
+
+ startFn := r.container.Start
+ if !r.create {
+ startFn = r.container.Run
+ }
+ // Setting up IO is a two stage process. We need to modify process to deal
+ // with detaching containers, and then we get a tty after the container has
+ // started.
+ handler := newSignalHandler(r.enableSubreaper)
+ tty, err := setupIO(process, rootuid, rootgid, config.Terminal, detach)
+ if err != nil {
+ r.destroy()
+ return -1, err
+ }
+ defer tty.Close()
+ if err = startFn(process); err != nil {
+ r.destroy()
+ return -1, err
+ }
+ if config.Terminal {
+ if err = tty.recvtty(process, r.detach || r.create); err != nil {
+ r.terminate(process)
+ r.destroy()
+ return -1, err
+ }
+ }
+
+ if config.Terminal && detach {
+ conn, err := net.Dial("unix", r.consoleSocket)
+ if err != nil {
+ r.terminate(process)
+ r.destroy()
+ return -1, err
+ }
+ defer conn.Close()
+
+ unixconn, ok := conn.(*net.UnixConn)
+ if !ok {
+ r.terminate(process)
+ r.destroy()
+ return -1, fmt.Errorf("casting to UnixConn failed")
+ }
+
+ socket, err := unixconn.File()
+ if err != nil {
+ r.terminate(process)
+ r.destroy()
+ return -1, err
+ }
+ defer socket.Close()
+
+ err = tty.sendtty(socket, r.terminalinfo())
+ if err != nil {
+ r.terminate(process)
+ r.destroy()
+ return -1, err
+ }
+ }
+
+ if err = tty.ClosePostStart(); err != nil {
+ r.terminate(process)
+ r.destroy()
+ return -1, err
+ }
+ if r.pidFile != "" {
+ if err = createPidFile(r.pidFile, process); err != nil {
+ r.terminate(process)
+ r.destroy()
+ return -1, err
+ }
+ }
+ if detach {
+ return 0, nil
+ }
+ status, err := handler.forward(process, tty)
+ if err != nil {
+ r.terminate(process)
+ }
+ r.destroy()
+ return status, err
+}
+
+func (r *runner) destroy() {
+ if r.shouldDestroy {
+ destroy(r.container)
+ }
+}
+
+func (r *runner) terminate(p *libcontainer.Process) {
+ _ = p.Signal(syscall.SIGKILL)
+ _, _ = p.Wait()
+}
+
+func validateProcessSpec(spec *specs.Process) error {
+ if spec.Cwd == "" {
+ return fmt.Errorf("Cwd property must not be empty")
+ }
+ if !filepath.IsAbs(spec.Cwd) {
+ return fmt.Errorf("Cwd must be an absolute path")
+ }
+ if len(spec.Args) == 0 {
+ return fmt.Errorf("args must not be empty")
+ }
+ return nil
+}
+
+func startContainer(context *cli.Context, spec *specs.Spec, create bool) (int, error) {
+ id := context.Args().First()
+ if id == "" {
+ return -1, errEmptyID
+ }
+ container, err := createContainer(context, id, spec)
+ if err != nil {
+ return -1, err
+ }
+ // Support on-demand socket activation by passing file descriptors into the container init process.
+ listenFDs := []*os.File{}
+ if os.Getenv("LISTEN_FDS") != "" {
+ listenFDs = activation.Files(false)
+ }
+ r := &runner{
+ enableSubreaper: !context.Bool("no-subreaper"),
+ shouldDestroy: true,
+ container: container,
+ listenFDs: listenFDs,
+ consoleSocket: context.String("console-socket"),
+ detach: context.Bool("detach"),
+ pidFile: context.String("pid-file"),
+ create: create,
+ }
+ return r.run(&spec.Process)
+}