diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json
index 6a0f3cb8..36cce276 100644
--- a/Godeps/Godeps.json
+++ b/Godeps/Godeps.json
@@ -9,8 +9,8 @@
},
{
"ImportPath": "github.com/docker/libcontainer",
- "Comment": "v1.1.0-194-gedfe81a",
- "Rev": "edfe81a08b2780ad75b63e60b6cb9eb3a17c671f"
+ "Comment": "v1.1.0-209-g55430d0",
+ "Rev": "55430d0db7c6bb1198c0bb573a9700a859d5ec26"
},
{
"ImportPath": "github.com/fsouza/go-dockerclient",
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/Makefile b/Godeps/_workspace/src/github.com/docker/libcontainer/Makefile
index d6852b24..4744c5ef 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/Makefile
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/Makefile
@@ -4,10 +4,10 @@ all:
test:
# we need NET_ADMIN for the netlink tests and SYS_ADMIN for mounting
- docker run --rm -it --cap-add NET_ADMIN --cap-add SYS_ADMIN docker/libcontainer
+ docker run --rm -it --privileged docker/libcontainer
sh:
- docker run --rm -it --cap-add NET_ADMIN --cap-add SYS_ADMIN -w /busybox docker/libcontainer nsinit exec sh
+ docker run --rm -it --privileged -w /busybox docker/libcontainer nsinit exec sh
GO_PACKAGES = $(shell find . -not \( -wholename ./vendor -prune \) -name '*.go' -print0 | xargs -0n1 dirname | sort -u)
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/cgroups.go b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/cgroups.go
index 59845486..567e9a6c 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/cgroups.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/cgroups.go
@@ -1,15 +1,11 @@
package cgroups
import (
- "errors"
+ "fmt"
"github.com/docker/libcontainer/devices"
)
-var (
- ErrNotFound = errors.New("mountpoint not found")
-)
-
type FreezerState string
const (
@@ -18,6 +14,29 @@ const (
Thawed FreezerState = "THAWED"
)
+type NotFoundError struct {
+ Subsystem string
+}
+
+func (e *NotFoundError) Error() string {
+ return fmt.Sprintf("mountpoint for %s not found", e.Subsystem)
+}
+
+func NewNotFoundError(sub string) error {
+ return &NotFoundError{
+ Subsystem: sub,
+ }
+}
+
+func IsNotFound(err error) bool {
+ if err == nil {
+ return false
+ }
+
+ _, ok := err.(*NotFoundError)
+ return ok
+}
+
type Cgroup struct {
Name string `json:"name,omitempty"`
Parent string `json:"parent,omitempty"` // name of parent cgroup or slice
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go
index e20cdbb9..443dbb69 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go
@@ -76,7 +76,7 @@ func GetStats(c *cgroups.Cgroup) (*cgroups.Stats, error) {
path, err := d.path(sysname)
if err != nil {
// Don't fail if a cgroup hierarchy was not found, just skip this subsystem
- if err == cgroups.ErrNotFound {
+ if cgroups.IsNotFound(err) {
continue
}
@@ -155,25 +155,45 @@ func (raw *data) parent(subsystem string) (string, error) {
func (raw *data) Paths() (map[string]string, error) {
paths := make(map[string]string)
+
for sysname := range subsystems {
path, err := raw.path(sysname)
if err != nil {
+ // Don't fail if a cgroup hierarchy was not found, just skip this subsystem
+ if cgroups.IsNotFound(err) {
+ continue
+ }
+
return nil, err
}
+
paths[sysname] = path
}
+
return paths, nil
}
func (raw *data) 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.cgroup) {
- return filepath.Join(raw.root, subsystem, raw.cgroup), nil
+ path := filepath.Join(raw.root, subsystem, raw.cgroup)
+
+ if _, err := os.Stat(path); err != nil {
+ if os.IsNotExist(err) {
+ return "", cgroups.NewNotFoundError(subsystem)
+ }
+
+ return "", err
+ }
+
+ return path, nil
}
+
parent, err := raw.parent(subsystem)
if err != nil {
return "", err
}
+
return filepath.Join(parent, raw.cgroup), nil
}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/blkio.go b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/blkio.go
index 38b87577..261a97ff 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/blkio.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/blkio.go
@@ -16,9 +16,10 @@ type BlkioGroup struct {
func (s *BlkioGroup) Set(d *data) error {
// we just want to join this group even though we don't set anything
- if _, err := d.join("blkio"); err != nil && err != cgroups.ErrNotFound {
+ if _, err := d.join("blkio"); err != nil && !cgroups.IsNotFound(err) {
return err
}
+
return nil
}
@@ -114,6 +115,14 @@ func getBlkioStat(path string) ([]cgroups.BlkioStatEntry, error) {
}
func (s *BlkioGroup) GetStats(path string, stats *cgroups.Stats) error {
+ // Try to read CFQ stats available on all CFQ enabled kernels first
+ if blkioStats, err := getBlkioStat(filepath.Join(path, "blkio.io_serviced_recursive")); err == nil && blkioStats != nil {
+ return getCFQStats(path, stats)
+ }
+ return getStats(path, stats) // Use generic stats as fallback
+}
+
+func getCFQStats(path string, stats *cgroups.Stats) error {
var blkioStats []cgroups.BlkioStatEntry
var err error
@@ -139,3 +148,20 @@ func (s *BlkioGroup) GetStats(path string, stats *cgroups.Stats) error {
return nil
}
+
+func getStats(path string, stats *cgroups.Stats) error {
+ var blkioStats []cgroups.BlkioStatEntry
+ var err error
+
+ if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.throttle.io_service_bytes")); err != nil {
+ return err
+ }
+ stats.BlkioStats.IoServiceBytesRecursive = blkioStats
+
+ if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.throttle.io_serviced")); err != nil {
+ return err
+ }
+ stats.BlkioStats.IoServicedRecursive = blkioStats
+
+ return nil
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/blkio_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/blkio_test.go
index db6f8d52..2a79d260 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/blkio_test.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/blkio_test.go
@@ -26,10 +26,30 @@ Total 50`
8:0 Async 3
8:0 Total 5
Total 5`
+ throttleServiceBytes = `8:0 Read 11030528
+8:0 Write 23
+8:0 Sync 42
+8:0 Async 11030528
+8:0 Total 11030528
+252:0 Read 11030528
+252:0 Write 23
+252:0 Sync 42
+252:0 Async 11030528
+252:0 Total 11030528
+Total 22061056`
+ throttleServiced = `8:0 Read 164
+8:0 Write 23
+8:0 Sync 42
+8:0 Async 164
+8:0 Total 164
+252:0 Read 164
+252:0 Write 23
+252:0 Sync 42
+252:0 Async 164
+252:0 Total 164
+Total 328`
)
-var actualStats = *cgroups.NewStats()
-
func appendBlkioStatEntry(blkioStatEntries *[]cgroups.BlkioStatEntry, major, minor, value uint64, op string) {
*blkioStatEntries = append(*blkioStatEntries, cgroups.BlkioStatEntry{Major: major, Minor: minor, Value: value, Op: op})
}
@@ -45,6 +65,7 @@ func TestBlkioStats(t *testing.T) {
})
blkio := &BlkioGroup{}
+ actualStats := *cgroups.NewStats()
err := blkio.GetStats(helper.CgroupPath, &actualStats)
if err != nil {
t.Fatal(err)
@@ -85,6 +106,7 @@ func TestBlkioStatsNoSectorsFile(t *testing.T) {
})
blkio := &BlkioGroup{}
+ actualStats := *cgroups.NewStats()
err := blkio.GetStats(helper.CgroupPath, &actualStats)
if err != nil {
t.Fatalf("Failed unexpectedly: %s", err)
@@ -101,6 +123,7 @@ func TestBlkioStatsNoServiceBytesFile(t *testing.T) {
})
blkio := &BlkioGroup{}
+ actualStats := *cgroups.NewStats()
err := blkio.GetStats(helper.CgroupPath, &actualStats)
if err != nil {
t.Fatalf("Failed unexpectedly: %s", err)
@@ -117,6 +140,7 @@ func TestBlkioStatsNoServicedFile(t *testing.T) {
})
blkio := &BlkioGroup{}
+ actualStats := *cgroups.NewStats()
err := blkio.GetStats(helper.CgroupPath, &actualStats)
if err != nil {
t.Fatalf("Failed unexpectedly: %s", err)
@@ -133,6 +157,7 @@ func TestBlkioStatsNoQueuedFile(t *testing.T) {
})
blkio := &BlkioGroup{}
+ actualStats := *cgroups.NewStats()
err := blkio.GetStats(helper.CgroupPath, &actualStats)
if err != nil {
t.Fatalf("Failed unexpectedly: %s", err)
@@ -150,6 +175,7 @@ func TestBlkioStatsUnexpectedNumberOfFields(t *testing.T) {
})
blkio := &BlkioGroup{}
+ actualStats := *cgroups.NewStats()
err := blkio.GetStats(helper.CgroupPath, &actualStats)
if err == nil {
t.Fatal("Expected to fail, but did not")
@@ -167,8 +193,56 @@ func TestBlkioStatsUnexpectedFieldType(t *testing.T) {
})
blkio := &BlkioGroup{}
+ actualStats := *cgroups.NewStats()
err := blkio.GetStats(helper.CgroupPath, &actualStats)
if err == nil {
t.Fatal("Expected to fail, but did not")
}
}
+
+func TestNonCFQBlkioStats(t *testing.T) {
+ helper := NewCgroupTestUtil("blkio", t)
+ defer helper.cleanup()
+ helper.writeFileContents(map[string]string{
+ "blkio.io_service_bytes_recursive": "",
+ "blkio.io_serviced_recursive": "",
+ "blkio.io_queued_recursive": "",
+ "blkio.sectors_recursive": "",
+ "blkio.throttle.io_service_bytes": throttleServiceBytes,
+ "blkio.throttle.io_serviced": throttleServiced,
+ })
+
+ blkio := &BlkioGroup{}
+ actualStats := *cgroups.NewStats()
+ err := blkio.GetStats(helper.CgroupPath, &actualStats)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ // Verify expected stats.
+ expectedStats := cgroups.BlkioStats{}
+
+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 11030528, "Read")
+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 23, "Write")
+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 42, "Sync")
+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 11030528, "Async")
+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 11030528, "Total")
+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 11030528, "Read")
+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 23, "Write")
+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 42, "Sync")
+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 11030528, "Async")
+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 11030528, "Total")
+
+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 164, "Read")
+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 23, "Write")
+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 42, "Sync")
+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 164, "Async")
+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 164, "Total")
+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 164, "Read")
+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 23, "Write")
+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 42, "Sync")
+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 164, "Async")
+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 164, "Total")
+
+ expectBlkioStatsEquals(t, expectedStats, actualStats.BlkioStats)
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/cpu_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/cpu_test.go
index 017a1f4b..2470e689 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/cpu_test.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/cpu_test.go
@@ -24,6 +24,7 @@ func TestCpuStats(t *testing.T) {
})
cpu := &CpuGroup{}
+ actualStats := *cgroups.NewStats()
err := cpu.GetStats(helper.CgroupPath, &actualStats)
if err != nil {
t.Fatal(err)
@@ -42,6 +43,7 @@ func TestNoCpuStatFile(t *testing.T) {
defer helper.cleanup()
cpu := &CpuGroup{}
+ actualStats := *cgroups.NewStats()
err := cpu.GetStats(helper.CgroupPath, &actualStats)
if err != nil {
t.Fatal("Expected not to fail, but did")
@@ -59,6 +61,7 @@ func TestInvalidCpuStat(t *testing.T) {
})
cpu := &CpuGroup{}
+ actualStats := *cgroups.NewStats()
err := cpu.GetStats(helper.CgroupPath, &actualStats)
if err == nil {
t.Fatal("Expected failed stat parsing.")
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/cpuacct.go b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/cpuacct.go
index 7761d4c2..853ab6bf 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/cpuacct.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/cpuacct.go
@@ -27,9 +27,10 @@ type CpuacctGroup struct {
func (s *CpuacctGroup) Set(d *data) error {
// we just want to join this group even though we don't set anything
- if _, err := d.join("cpuacct"); err != nil && err != cgroups.ErrNotFound {
+ if _, err := d.join("cpuacct"); err != nil && !cgroups.IsNotFound(err) {
return err
}
+
return nil
}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/freezer.go b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/freezer.go
index db2a41ca..c6b677fa 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/freezer.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/freezer.go
@@ -33,7 +33,7 @@ func (s *FreezerGroup) Set(d *data) error {
time.Sleep(1 * time.Millisecond)
}
default:
- if _, err := d.join("freezer"); err != nil && err != cgroups.ErrNotFound {
+ if _, err := d.join("freezer"); err != nil && !cgroups.IsNotFound(err) {
return err
}
}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/fs.test b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/fs.test
deleted file mode 100644
index 7d61b991..00000000
Binary files a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/fs.test and /dev/null differ
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/memory_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/memory_test.go
index e92f1daf..a21cec75 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/memory_test.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/memory_test.go
@@ -25,6 +25,7 @@ func TestMemoryStats(t *testing.T) {
})
memory := &MemoryGroup{}
+ actualStats := *cgroups.NewStats()
err := memory.GetStats(helper.CgroupPath, &actualStats)
if err != nil {
t.Fatal(err)
@@ -42,6 +43,7 @@ func TestMemoryStatsNoStatFile(t *testing.T) {
})
memory := &MemoryGroup{}
+ actualStats := *cgroups.NewStats()
err := memory.GetStats(helper.CgroupPath, &actualStats)
if err != nil {
t.Fatal(err)
@@ -57,6 +59,7 @@ func TestMemoryStatsNoUsageFile(t *testing.T) {
})
memory := &MemoryGroup{}
+ actualStats := *cgroups.NewStats()
err := memory.GetStats(helper.CgroupPath, &actualStats)
if err == nil {
t.Fatal("Expected failure")
@@ -72,6 +75,7 @@ func TestMemoryStatsNoMaxUsageFile(t *testing.T) {
})
memory := &MemoryGroup{}
+ actualStats := *cgroups.NewStats()
err := memory.GetStats(helper.CgroupPath, &actualStats)
if err == nil {
t.Fatal("Expected failure")
@@ -88,6 +92,7 @@ func TestMemoryStatsBadStatFile(t *testing.T) {
})
memory := &MemoryGroup{}
+ actualStats := *cgroups.NewStats()
err := memory.GetStats(helper.CgroupPath, &actualStats)
if err == nil {
t.Fatal("Expected failure")
@@ -104,6 +109,7 @@ func TestMemoryStatsBadUsageFile(t *testing.T) {
})
memory := &MemoryGroup{}
+ actualStats := *cgroups.NewStats()
err := memory.GetStats(helper.CgroupPath, &actualStats)
if err == nil {
t.Fatal("Expected failure")
@@ -120,6 +126,7 @@ func TestMemoryStatsBadMaxUsageFile(t *testing.T) {
})
memory := &MemoryGroup{}
+ actualStats := *cgroups.NewStats()
err := memory.GetStats(helper.CgroupPath, &actualStats)
if err == nil {
t.Fatal("Expected failure")
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/perf_event.go b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/perf_event.go
index 5f45678f..813274d8 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/perf_event.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/perf_event.go
@@ -9,7 +9,7 @@ type PerfEventGroup struct {
func (s *PerfEventGroup) Set(d *data) error {
// we just want to join this group even though we don't set anything
- if _, err := d.join("perf_event"); err != nil && err != cgroups.ErrNotFound {
+ if _, err := d.join("perf_event"); err != nil && !cgroups.IsNotFound(err) {
return err
}
return nil
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/utils_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/utils_test.go
index 6ea59bc5..63d743f0 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/utils_test.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/utils_test.go
@@ -5,8 +5,6 @@ import (
"os"
"path/filepath"
"testing"
-
- "github.com/docker/libcontainer/cgroups"
)
const (
@@ -68,20 +66,3 @@ func TestGetCgroupParamsInt(t *testing.T) {
t.Fatal("Expecting error, got none")
}
}
-
-func TestAbsolutePathHandling(t *testing.T) {
- testCgroup := cgroups.Cgroup{
- Name: "bar",
- Parent: "/foo",
- }
- cgroupData := data{
- root: "/sys/fs/cgroup",
- cgroup: "/foo/bar",
- c: &testCgroup,
- pid: 1,
- }
- expectedPath := filepath.Join(cgroupData.root, "cpu", testCgroup.Parent, testCgroup.Name)
- if path, err := cgroupData.path("cpu"); path != expectedPath || err != nil {
- t.Fatalf("expected path %s but got %s %s", expectedPath, path, err)
- }
-}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go
index 252fb60e..7af4818e 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go
@@ -166,7 +166,7 @@ func (c *systemdCgroup) Paths() (map[string]string, error) {
subsystemPath, err := getSubsystemPath(c.cgroup, sysname)
if err != nil {
// Don't fail if a cgroup hierarchy was not found, just skip this subsystem
- if err == cgroups.ErrNotFound {
+ if cgroups.IsNotFound(err) {
continue
}
@@ -274,7 +274,7 @@ func GetStats(c *cgroups.Cgroup) (*cgroups.Stats, error) {
subsystemPath, err := getSubsystemPath(c, sysname)
if err != nil {
// Don't fail if a cgroup hierarchy was not found, just skip this subsystem
- if err == cgroups.ErrNotFound {
+ if cgroups.IsNotFound(err) {
continue
}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/utils.go b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/utils.go
index 6688ff71..5516c5a2 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/utils.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/utils.go
@@ -29,7 +29,8 @@ func FindCgroupMountpoint(subsystem string) (string, error) {
}
}
}
- return "", ErrNotFound
+
+ return "", NewNotFoundError(subsystem)
}
type Mount struct {
@@ -153,19 +154,23 @@ func ReadProcsFile(dir string) ([]int, error) {
func parseCgroupFile(subsystem string, r io.Reader) (string, error) {
s := bufio.NewScanner(r)
+
for s.Scan() {
if err := s.Err(); err != nil {
return "", err
}
+
text := s.Text()
parts := strings.Split(text, ":")
+
for _, subs := range strings.Split(parts[1], ",") {
if subs == subsystem {
return parts[2], nil
}
}
}
- return "", ErrNotFound
+
+ return "", NewNotFoundError(subsystem)
}
func pathExists(path string) bool {
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/container.go b/Godeps/_workspace/src/github.com/docker/libcontainer/container.go
index c4d372ce..ace997b7 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/container.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/container.go
@@ -9,8 +9,8 @@ package libcontainer
// be destroyed by a separate process, any function may return that the container
// was not found.
type Container interface {
- // Returns the path to the container which contains the state
- Path() string
+ // Returns the ID of the container
+ ID() string
// Returns the current run state of the container.
//
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/factory.go b/Godeps/_workspace/src/github.com/docker/libcontainer/factory.go
index 9161ff05..b7449335 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/factory.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/factory.go
@@ -12,14 +12,14 @@ type Factory interface {
// System error
//
// On error, any partially created container parts are cleaned up (the operation is atomic).
- Create(path string, config *Config) (Container, error)
+ Create(id string, config *Config) (Container, error)
- // Load takes the path for an existing container and reconstructs the container
+ // Load takes an ID for an existing container and reconstructs the container
// from the state.
//
// Errors:
// Path does not exist
// Container is stopped
// System error
- Load(path string) (Container, error)
+ Load(id string) (Container, error)
}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/label/label.go b/Godeps/_workspace/src/github.com/docker/libcontainer/label/label.go
index 73869b36..ce60296e 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/label/label.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/label/label.go
@@ -39,3 +39,7 @@ func Init() {
func ReserveLabel(label string) error {
return nil
}
+
+func UnreserveLabel(label string) error {
+ return nil
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/label/label_selinux.go b/Godeps/_workspace/src/github.com/docker/libcontainer/label/label_selinux.go
index 5b1380a2..0a9a8205 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/label/label_selinux.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/label/label_selinux.go
@@ -128,3 +128,11 @@ func ReserveLabel(label string) error {
selinux.ReserveLabel(label)
return nil
}
+
+// UnreserveLabel will remove the reservation of the MCS label.
+// This will allow InitLabels to use the MCS label in a newly created
+// containers
+func UnreserveLabel(label string) error {
+ selinux.FreeLxcContexts(label)
+ return nil
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/mount/init.go b/Godeps/_workspace/src/github.com/docker/libcontainer/mount/init.go
index 05ab334c..ea2b7327 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/mount/init.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/mount/init.go
@@ -8,7 +8,6 @@ import (
"path/filepath"
"syscall"
- "github.com/docker/docker/pkg/symlink"
"github.com/docker/libcontainer/label"
"github.com/docker/libcontainer/mount/nodes"
)
@@ -31,24 +30,34 @@ func InitializeMountNamespace(rootfs, console string, sysReadonly bool, mountCon
err error
flag = syscall.MS_PRIVATE
)
+
if mountConfig.NoPivotRoot {
flag = syscall.MS_SLAVE
}
+
if err := syscall.Mount("", "/", "", uintptr(flag|syscall.MS_REC), ""); err != nil {
return fmt.Errorf("mounting / with flags %X %s", (flag | syscall.MS_REC), err)
}
+
if err := syscall.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil {
return fmt.Errorf("mouting %s as bind %s", rootfs, err)
}
+
if err := mountSystem(rootfs, sysReadonly, mountConfig); err != nil {
return fmt.Errorf("mount system %s", err)
}
- if err := setupBindmounts(rootfs, mountConfig); err != nil {
- return fmt.Errorf("bind mounts %s", err)
+
+ // apply any user specified mounts within the new mount namespace
+ for _, m := range mountConfig.Mounts {
+ if err := m.Mount(rootfs, mountConfig.MountLabel); err != nil {
+ return err
+ }
}
+
if err := nodes.CreateDeviceNodes(rootfs, mountConfig.DeviceNodes); err != nil {
return fmt.Errorf("create device nodes %s", err)
}
+
if err := SetupPtmx(rootfs, console, mountConfig.MountLabel); err != nil {
return err
}
@@ -72,6 +81,7 @@ func InitializeMountNamespace(rootfs, console string, sysReadonly bool, mountCon
} else {
err = PivotRoot(rootfs)
}
+
if err != nil {
return err
}
@@ -90,7 +100,7 @@ func InitializeMountNamespace(rootfs, console string, sysReadonly bool, mountCon
// mountSystem sets up linux specific system mounts like sys, proc, shm, and devpts
// inside the mount namespace
func mountSystem(rootfs string, sysReadonly bool, mountConfig *MountConfig) error {
- for _, m := range newSystemMounts(rootfs, mountConfig.MountLabel, sysReadonly, mountConfig.Mounts) {
+ for _, m := range newSystemMounts(rootfs, mountConfig.MountLabel, sysReadonly) {
if err := os.MkdirAll(m.path, 0755); err != nil && !os.IsExist(err) {
return fmt.Errorf("mkdirall %s %s", m.path, err)
}
@@ -151,56 +161,9 @@ func setupDevSymlinks(rootfs string) error {
return nil
}
-func setupBindmounts(rootfs string, mountConfig *MountConfig) error {
- bindMounts := mountConfig.Mounts
- for _, m := range bindMounts.OfType("bind") {
- var (
- flags = syscall.MS_BIND | syscall.MS_REC
- dest = filepath.Join(rootfs, m.Destination)
- )
- if !m.Writable {
- flags = flags | syscall.MS_RDONLY
- }
-
- stat, err := os.Stat(m.Source)
- if err != nil {
- return err
- }
-
- dest, err = symlink.FollowSymlinkInScope(dest, rootfs)
- if err != nil {
- return err
- }
-
- if err := createIfNotExists(dest, stat.IsDir()); err != nil {
- return fmt.Errorf("Creating new bind-mount target, %s", err)
- }
-
- if err := syscall.Mount(m.Source, dest, "bind", uintptr(flags), ""); err != nil {
- return fmt.Errorf("mounting %s into %s %s", m.Source, dest, err)
- }
- if !m.Writable {
- if err := syscall.Mount(m.Source, dest, "bind", uintptr(flags|syscall.MS_REMOUNT), ""); err != nil {
- return fmt.Errorf("remounting %s into %s %s", m.Source, dest, err)
- }
- }
- if m.Relabel != "" {
- if err := label.Relabel(m.Source, mountConfig.MountLabel, m.Relabel); err != nil {
- return fmt.Errorf("relabeling %s to %s %s", m.Source, mountConfig.MountLabel, err)
- }
- }
- if m.Private {
- if err := syscall.Mount("", dest, "none", uintptr(syscall.MS_PRIVATE), ""); err != nil {
- return fmt.Errorf("mounting %s private %s", dest, err)
- }
- }
- }
- return nil
-}
-
// TODO: this is crappy right now and should be cleaned up with a better way of handling system and
// standard bind mounts allowing them to be more dynamic
-func newSystemMounts(rootfs, mountLabel string, sysReadonly bool, mounts Mounts) []mount {
+func newSystemMounts(rootfs, mountLabel string, sysReadonly bool) []mount {
systemMounts := []mount{
{source: "proc", path: filepath.Join(rootfs, "proc"), device: "proc", flags: defaultMountFlags},
{source: "tmpfs", path: filepath.Join(rootfs, "dev"), device: "tmpfs", flags: syscall.MS_NOSUID | syscall.MS_STRICTATIME, data: label.FormatMountLabel("mode=755", mountLabel)},
@@ -212,6 +175,7 @@ func newSystemMounts(rootfs, mountLabel string, sysReadonly bool, mounts Mounts)
if sysReadonly {
sysMountFlags |= syscall.MS_RDONLY
}
+
systemMounts = append(systemMounts, mount{source: "sysfs", path: filepath.Join(rootfs, "sys"), device: "sysfs", flags: sysMountFlags})
return systemMounts
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/mount/mount.go b/Godeps/_workspace/src/github.com/docker/libcontainer/mount/mount.go
new file mode 100644
index 00000000..c7865b3c
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/mount/mount.go
@@ -0,0 +1,104 @@
+package mount
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "syscall"
+
+ "github.com/docker/docker/pkg/symlink"
+ "github.com/docker/libcontainer/label"
+)
+
+type Mount struct {
+ Type string `json:"type,omitempty"`
+ Source string `json:"source,omitempty"` // Source path, in the host namespace
+ Destination string `json:"destination,omitempty"` // Destination path, in the container
+ Writable bool `json:"writable,omitempty"`
+ Relabel string `json:"relabel,omitempty"` // Relabel source if set, "z" indicates shared, "Z" indicates unshared
+ Private bool `json:"private,omitempty"`
+}
+
+func (m *Mount) Mount(rootfs, mountLabel string) error {
+ switch m.Type {
+ case "bind":
+ return m.bindMount(rootfs, mountLabel)
+ case "tmpfs":
+ return m.tmpfsMount(rootfs, mountLabel)
+ default:
+ return fmt.Errorf("unsupported mount type %s for %s", m.Type, m.Destination)
+ }
+}
+
+func (m *Mount) bindMount(rootfs, mountLabel string) error {
+ var (
+ flags = syscall.MS_BIND | syscall.MS_REC
+ dest = filepath.Join(rootfs, m.Destination)
+ )
+
+ if !m.Writable {
+ flags = flags | syscall.MS_RDONLY
+ }
+
+ stat, err := os.Stat(m.Source)
+ if err != nil {
+ return err
+ }
+
+ // FIXME: (crosbymichael) This does not belong here and should be done a layer above
+ dest, err = symlink.FollowSymlinkInScope(dest, rootfs)
+ if err != nil {
+ return err
+ }
+
+ if err := createIfNotExists(dest, stat.IsDir()); err != nil {
+ return fmt.Errorf("creating new bind mount target %s", err)
+ }
+
+ if err := syscall.Mount(m.Source, dest, "bind", uintptr(flags), ""); err != nil {
+ return fmt.Errorf("mounting %s into %s %s", m.Source, dest, err)
+ }
+
+ if !m.Writable {
+ if err := syscall.Mount(m.Source, dest, "bind", uintptr(flags|syscall.MS_REMOUNT), ""); err != nil {
+ return fmt.Errorf("remounting %s into %s %s", m.Source, dest, err)
+ }
+ }
+
+ if m.Relabel != "" {
+ if err := label.Relabel(m.Source, mountLabel, m.Relabel); err != nil {
+ return fmt.Errorf("relabeling %s to %s %s", m.Source, mountLabel, err)
+ }
+ }
+
+ if m.Private {
+ if err := syscall.Mount("", dest, "none", uintptr(syscall.MS_PRIVATE), ""); err != nil {
+ return fmt.Errorf("mounting %s private %s", dest, err)
+ }
+ }
+
+ return nil
+}
+
+func (m *Mount) tmpfsMount(rootfs, mountLabel string) error {
+ var (
+ err error
+ l = label.FormatMountLabel("", mountLabel)
+ dest = filepath.Join(rootfs, m.Destination)
+ )
+
+ // FIXME: (crosbymichael) This does not belong here and should be done a layer above
+ if dest, err = symlink.FollowSymlinkInScope(dest, rootfs); err != nil {
+ return err
+ }
+
+ if err := createIfNotExists(dest, true); err != nil {
+ return fmt.Errorf("creating new tmpfs mount target %s", err)
+ }
+
+ if err := syscall.Mount("tmpfs", dest, "tmpfs", uintptr(defaultMountFlags), l); err != nil {
+ return fmt.Errorf("%s mounting %s in tmpfs", err, dest)
+ }
+
+ return nil
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/mount/types.go b/Godeps/_workspace/src/github.com/docker/libcontainer/mount/mount_config.go
similarity index 59%
rename from Godeps/_workspace/src/github.com/docker/libcontainer/mount/types.go
rename to Godeps/_workspace/src/github.com/docker/libcontainer/mount/mount_config.go
index 063bbac1..eef9b8ce 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/mount/types.go
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/mount/mount_config.go
@@ -6,6 +6,8 @@ import (
"github.com/docker/libcontainer/devices"
)
+var ErrUnsupported = errors.New("Unsupported method")
+
type MountConfig struct {
// NoPivotRoot will use MS_MOVE and a chroot to jail the process into the container's rootfs
// This is a common option when the container is running in ramdisk
@@ -17,33 +19,10 @@ type MountConfig struct {
// Mounts specify additional source and destination paths that will be mounted inside the container's
// rootfs and mount namespace if specified
- Mounts Mounts `json:"mounts,omitempty"`
+ Mounts []*Mount `json:"mounts,omitempty"`
// The device nodes that should be automatically created within the container upon container start. Note, make sure that the node is marked as allowed in the cgroup as well!
DeviceNodes []*devices.Device `json:"device_nodes,omitempty"`
MountLabel string `json:"mount_label,omitempty"`
}
-
-type Mount struct {
- Type string `json:"type,omitempty"`
- Source string `json:"source,omitempty"` // Source path, in the host namespace
- Destination string `json:"destination,omitempty"` // Destination path, in the container
- Writable bool `json:"writable,omitempty"`
- Relabel string `json:"relabel,omitempty"` // Relabel source if set, "z" indicates shared, "Z" indicates unshared
- Private bool `json:"private,omitempty"`
-}
-
-type Mounts []Mount
-
-var ErrUnsupported = errors.New("Unsupported method")
-
-func (s Mounts) OfType(t string) Mounts {
- out := Mounts{}
- for _, m := range s {
- if m.Type == t {
- out = append(out, m)
- }
- }
- return out
-}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink.test b/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink.test
deleted file mode 100644
index 3ba78ff0..00000000
Binary files a/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink.test and /dev/null differ
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/main/main b/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/main/main
deleted file mode 100644
index fca84309..00000000
Binary files a/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/main/main and /dev/null differ
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/main/nsinit b/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/main/nsinit
deleted file mode 100644
index 3c9209d7..00000000
Binary files a/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/main/nsinit and /dev/null differ
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/nsinit b/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/nsinit
deleted file mode 100644
index 0b51cf40..00000000
Binary files a/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/nsinit and /dev/null differ
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/nsinitb b/Godeps/_workspace/src/github.com/docker/libcontainer/nsinitb
deleted file mode 100644
index f9d2a6a3..00000000
Binary files a/Godeps/_workspace/src/github.com/docker/libcontainer/nsinitb and /dev/null differ
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/minimal.json b/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/minimal.json
index c08c9967..8d85ddf7 100644
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/minimal.json
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/minimal.json
@@ -166,6 +166,12 @@
"path": "/dev/random",
"type": 99
}
+ ],
+ "mounts": [
+ {
+ "type": "tmpfs",
+ "destination": "/tmp"
+ }
]
},
"environment": [
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/security/capabilities/capabilities.test b/Godeps/_workspace/src/github.com/docker/libcontainer/security/capabilities/capabilities.test
deleted file mode 100644
index debc8d5e..00000000
Binary files a/Godeps/_workspace/src/github.com/docker/libcontainer/security/capabilities/capabilities.test and /dev/null differ
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/test/utils.go b/Godeps/_workspace/src/github.com/docker/libcontainer/test/utils.go
deleted file mode 100644
index 6283d84b..00000000
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/test/utils.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package libcontainer
-
-import (
- "github.com/docker/libcontainer"
- "github.com/docker/libcontainer/security/capabilities"
-)
-
-func GetAllCapabilities() []string {
- return capabilities.GetAllCapabilities()
-}
-
-func DropBoundingSet(container *libcontainer.Config) error {
- return capabilities.DropBoundingSet(container.Capabilities)
-}
-
-func DropCapabilities(container *libcontainer.Config) error {
- return capabilities.DropCapabilities(container.Capabilities)
-}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/test/utils.go~ b/Godeps/_workspace/src/github.com/docker/libcontainer/test/utils.go~
deleted file mode 100644
index 55239a25..00000000
--- a/Godeps/_workspace/src/github.com/docker/libcontainer/test/utils.go~
+++ /dev/null
@@ -1,18 +0,0 @@
-package libcontainer
-
-import (
- "github.com/docker/libcontainer"
- "github.com/docker/libcontainer/security/capabilities"
-)
-
-func GetAllCapabilities() []string {
- return capabilities.GetAllCapabilities()
-}
-
-func DropBoundingSet(container *libcontainer.Container) error {
- return capabilities.DropBoundingSet(container.Capabilities)
-}
-
-func DropCapabilities(container *libcontainer.Container) error {
- return capabilities.DropCapabilities(container.Capabilities)
-}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/update-vendor.sh b/Godeps/_workspace/src/github.com/docker/libcontainer/update-vendor.sh
new file mode 100644
index 00000000..df66a0a8
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/update-vendor.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+set -e
+
+cd "$(dirname "$BASH_SOURCE")"
+
+# Downloads dependencies into vendor/ directory
+mkdir -p vendor
+cd vendor
+
+clone() {
+ vcs=$1
+ pkg=$2
+ rev=$3
+
+ pkg_url=https://$pkg
+ target_dir=src/$pkg
+
+ echo -n "$pkg @ $rev: "
+
+ if [ -d $target_dir ]; then
+ echo -n 'rm old, '
+ rm -fr $target_dir
+ fi
+
+ echo -n 'clone, '
+ case $vcs in
+ git)
+ git clone --quiet --no-checkout $pkg_url $target_dir
+ ( cd $target_dir && git reset --quiet --hard $rev )
+ ;;
+ hg)
+ hg clone --quiet --updaterev $rev $pkg_url $target_dir
+ ;;
+ esac
+
+ echo -n 'rm VCS, '
+ ( cd $target_dir && rm -rf .{git,hg} )
+
+ echo done
+}
+
+# the following lines are in sorted order, FYI
+clone git github.com/codegangsta/cli 1.1.0
+clone git github.com/coreos/go-systemd v2
+clone git github.com/godbus/dbus v1
+clone git github.com/syndtr/gocapability 3c85049eae
+
+# intentionally not vendoring Docker itself... that'd be a circle :)
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/.travis.yml b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/.travis.yml
new file mode 100644
index 00000000..baf46abc
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/.travis.yml
@@ -0,0 +1,6 @@
+language: go
+go: 1.1
+
+script:
+- go vet ./...
+- go test -v ./...
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/LICENSE b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/LICENSE
new file mode 100644
index 00000000..5515ccfb
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/LICENSE
@@ -0,0 +1,21 @@
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/README.md b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/README.md
new file mode 100644
index 00000000..59806f4b
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/README.md
@@ -0,0 +1,257 @@
+[](https://travis-ci.org/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.
+
+You can view the API docs here:
+http://godoc.org/github.com/codegangsta/cli
+
+## 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!
+
+``` go
+/* greet.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 some bitchass 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)
+ }
+}
+...
+```
+
+#### 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.
+
+### Subcommands
+
+Subcommands can be defined for a more git-like command line app.
+```go
+...
+app.Commands = []cli.Command{
+ {
+ Name: "add",
+ ShortName: "a",
+ Usage: "add a task to the list",
+ Action: func(c *cli.Context) {
+ println("added task: ", c.Args().First())
+ },
+ },
+ {
+ Name: "complete",
+ ShortName: "c",
+ Usage: "complete a task on the list",
+ Action: func(c *cli.Context) {
+ println("completed task: ", c.Args().First())
+ },
+ },
+ {
+ Name: "template",
+ ShortName: "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",
+ ShortName: "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 {
+ 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`
+
+
+## About
+cli.go is written by none other than the [Code Gangsta](http://codegangsta.io)
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/app.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/app.go
new file mode 100644
index 00000000..e193b828
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/app.go
@@ -0,0 +1,248 @@
+package cli
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "time"
+)
+
+// App is the main structure of a cli application. It is recomended that
+// and app be created with the cli.NewApp() function
+type App struct {
+ // The name of the program. Defaults to os.Args[0]
+ Name string
+ // Description of the program.
+ Usage 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
+ // 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
+ // 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
+ // Author
+ Author string
+ // Author e-mail
+ Email string
+}
+
+// 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: os.Args[0],
+ Usage: "A new cli application",
+ Version: "0.0.0",
+ BashComplete: DefaultAppComplete,
+ Action: helpCommand.Action,
+ Compiled: compileTime(),
+ Author: "Author",
+ Email: "unknown@email",
+ }
+}
+
+// Entry point to the cli app. Parses the arguments slice and routes to the proper flag/args combination
+func (a *App) Run(arguments []string) error {
+ // append help to commands
+ if a.Command(helpCommand.Name) == nil && !a.HideHelp {
+ a.Commands = append(a.Commands, helpCommand)
+ a.appendFlag(HelpFlag)
+ }
+
+ //append version/help flags
+ if a.EnableBashCompletion {
+ a.appendFlag(BashCompletionFlag)
+ }
+ 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.Println(nerr)
+ context := NewContext(a, set, set)
+ ShowAppHelp(context)
+ fmt.Println("")
+ return nerr
+ }
+ context := NewContext(a, set, set)
+
+ if err != nil {
+ fmt.Printf("Incorrect Usage.\n\n")
+ ShowAppHelp(context)
+ fmt.Println("")
+ return err
+ }
+
+ if checkCompletions(context) {
+ return nil
+ }
+
+ if checkHelp(context) {
+ return nil
+ }
+
+ if checkVersion(context) {
+ return nil
+ }
+
+ 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 {
+ os.Stderr.WriteString(fmt.Sprintln(err))
+ os.Exit(1)
+ }
+}
+
+// Invokes the subcommand given the context, parses ctx.Args() to generate command-specific flags
+func (a *App) RunAsSubcommand(ctx *Context) error {
+ // append help to commands
+ if len(a.Commands) > 0 {
+ if a.Command(helpCommand.Name) == nil && !a.HideHelp {
+ a.Commands = append(a.Commands, helpCommand)
+ a.appendFlag(HelpFlag)
+ }
+ }
+
+ // 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.globalSet)
+
+ if nerr != nil {
+ fmt.Println(nerr)
+ if len(a.Commands) > 0 {
+ ShowSubcommandHelp(context)
+ } else {
+ ShowCommandHelp(ctx, context.Args().First())
+ }
+ fmt.Println("")
+ return nerr
+ }
+
+ if err != nil {
+ fmt.Printf("Incorrect Usage.\n\n")
+ ShowSubcommandHelp(context)
+ return err
+ }
+
+ if checkCompletions(context) {
+ return nil
+ }
+
+ if len(a.Commands) > 0 {
+ if checkSubcommandHelp(context) {
+ return nil
+ }
+ } else {
+ if checkCommandHelp(ctx, context.Args().First()) {
+ return nil
+ }
+ }
+
+ 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
+ if len(a.Commands) > 0 {
+ a.Action(context)
+ } else {
+ a.Action(ctx)
+ }
+
+ 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)
+ }
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/app_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/app_test.go
new file mode 100644
index 00000000..a9156241
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/app_test.go
@@ -0,0 +1,399 @@
+package cli_test
+
+import (
+ "fmt"
+ "os"
+ "testing"
+
+ "github.com/codegangsta/cli"
+)
+
+func ExampleApp() {
+ // set args for examples sake
+ os.Args = []string{"greet", "--name", "Jeremy"}
+
+ app := cli.NewApp()
+ app.Name = "greet"
+ app.Flags = []cli.Flag{
+ cli.StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
+ }
+ app.Action = func(c *cli.Context) {
+ fmt.Printf("Hello %v\n", c.String("name"))
+ }
+ app.Run(os.Args)
+ // Output:
+ // Hello Jeremy
+}
+
+func ExampleAppSubcommand() {
+ // set args for examples sake
+ os.Args = []string{"say", "hi", "english", "--name", "Jeremy"}
+ app := cli.NewApp()
+ app.Name = "say"
+ app.Commands = []cli.Command{
+ {
+ Name: "hello",
+ ShortName: "hi",
+ Usage: "use it to see a description",
+ Description: "This is how we describe hello the function",
+ Subcommands: []cli.Command{
+ {
+ Name: "english",
+ ShortName: "en",
+ Usage: "sends a greeting in english",
+ Description: "greets someone in english",
+ Flags: []cli.Flag{
+ cli.StringFlag{Name: "name", Value: "Bob", Usage: "Name of the person to greet"},
+ },
+ Action: func(c *cli.Context) {
+ fmt.Println("Hello,", c.String("name"))
+ },
+ },
+ },
+ },
+ }
+
+ app.Run(os.Args)
+ // Output:
+ // Hello, Jeremy
+}
+
+func ExampleAppHelp() {
+ // set args for examples sake
+ os.Args = []string{"greet", "h", "describeit"}
+
+ app := cli.NewApp()
+ app.Name = "greet"
+ app.Flags = []cli.Flag{
+ cli.StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
+ }
+ app.Commands = []cli.Command{
+ {
+ Name: "describeit",
+ ShortName: "d",
+ Usage: "use it to see a description",
+ Description: "This is how we describe describeit the function",
+ Action: func(c *cli.Context) {
+ fmt.Printf("i like to describe things")
+ },
+ },
+ }
+ app.Run(os.Args)
+ // Output:
+ // NAME:
+ // describeit - use it to see a description
+ //
+ // USAGE:
+ // command describeit [arguments...]
+ //
+ // DESCRIPTION:
+ // This is how we describe describeit the function
+}
+
+func ExampleAppBashComplete() {
+ // set args for examples sake
+ os.Args = []string{"greet", "--generate-bash-completion"}
+
+ app := cli.NewApp()
+ app.Name = "greet"
+ app.EnableBashCompletion = true
+ app.Commands = []cli.Command{
+ {
+ Name: "describeit",
+ ShortName: "d",
+ Usage: "use it to see a description",
+ Description: "This is how we describe describeit the function",
+ Action: func(c *cli.Context) {
+ fmt.Printf("i like to describe things")
+ },
+ }, {
+ Name: "next",
+ Usage: "next example",
+ Description: "more stuff to see when generating bash completion",
+ Action: func(c *cli.Context) {
+ fmt.Printf("the next example")
+ },
+ },
+ }
+
+ app.Run(os.Args)
+ // Output:
+ // describeit
+ // d
+ // next
+ // help
+ // h
+}
+
+func TestApp_Run(t *testing.T) {
+ s := ""
+
+ app := cli.NewApp()
+ app.Action = func(c *cli.Context) {
+ s = s + c.Args().First()
+ }
+
+ err := app.Run([]string{"command", "foo"})
+ expect(t, err, nil)
+ err = app.Run([]string{"command", "bar"})
+ expect(t, err, nil)
+ expect(t, s, "foobar")
+}
+
+var commandAppTests = []struct {
+ name string
+ expected bool
+}{
+ {"foobar", true},
+ {"batbaz", true},
+ {"b", true},
+ {"f", true},
+ {"bat", false},
+ {"nothing", false},
+}
+
+func TestApp_Command(t *testing.T) {
+ app := cli.NewApp()
+ fooCommand := cli.Command{Name: "foobar", ShortName: "f"}
+ batCommand := cli.Command{Name: "batbaz", ShortName: "b"}
+ app.Commands = []cli.Command{
+ fooCommand,
+ batCommand,
+ }
+
+ for _, test := range commandAppTests {
+ expect(t, app.Command(test.name) != nil, test.expected)
+ }
+}
+
+func TestApp_CommandWithArgBeforeFlags(t *testing.T) {
+ var parsedOption, firstArg string
+
+ app := cli.NewApp()
+ command := cli.Command{
+ Name: "cmd",
+ Flags: []cli.Flag{
+ cli.StringFlag{Name: "option", Value: "", Usage: "some option"},
+ },
+ Action: func(c *cli.Context) {
+ parsedOption = c.String("option")
+ firstArg = c.Args().First()
+ },
+ }
+ app.Commands = []cli.Command{command}
+
+ app.Run([]string{"", "cmd", "my-arg", "--option", "my-option"})
+
+ expect(t, parsedOption, "my-option")
+ expect(t, firstArg, "my-arg")
+}
+
+func TestApp_Float64Flag(t *testing.T) {
+ var meters float64
+
+ app := cli.NewApp()
+ app.Flags = []cli.Flag{
+ cli.Float64Flag{Name: "height", Value: 1.5, Usage: "Set the height, in meters"},
+ }
+ app.Action = func(c *cli.Context) {
+ meters = c.Float64("height")
+ }
+
+ app.Run([]string{"", "--height", "1.93"})
+ expect(t, meters, 1.93)
+}
+
+func TestApp_ParseSliceFlags(t *testing.T) {
+ var parsedOption, firstArg string
+ var parsedIntSlice []int
+ var parsedStringSlice []string
+
+ app := cli.NewApp()
+ command := cli.Command{
+ Name: "cmd",
+ Flags: []cli.Flag{
+ cli.IntSliceFlag{Name: "p", Value: &cli.IntSlice{}, Usage: "set one or more ip addr"},
+ cli.StringSliceFlag{Name: "ip", Value: &cli.StringSlice{}, Usage: "set one or more ports to open"},
+ },
+ Action: func(c *cli.Context) {
+ parsedIntSlice = c.IntSlice("p")
+ parsedStringSlice = c.StringSlice("ip")
+ parsedOption = c.String("option")
+ firstArg = c.Args().First()
+ },
+ }
+ app.Commands = []cli.Command{command}
+
+ app.Run([]string{"", "cmd", "my-arg", "-p", "22", "-p", "80", "-ip", "8.8.8.8", "-ip", "8.8.4.4"})
+
+ IntsEquals := func(a, b []int) bool {
+ if len(a) != len(b) {
+ return false
+ }
+ for i, v := range a {
+ if v != b[i] {
+ return false
+ }
+ }
+ return true
+ }
+
+ StrsEquals := func(a, b []string) bool {
+ if len(a) != len(b) {
+ return false
+ }
+ for i, v := range a {
+ if v != b[i] {
+ return false
+ }
+ }
+ return true
+ }
+ var expectedIntSlice = []int{22, 80}
+ var expectedStringSlice = []string{"8.8.8.8", "8.8.4.4"}
+
+ if !IntsEquals(parsedIntSlice, expectedIntSlice) {
+ t.Errorf("%v does not match %v", parsedIntSlice, expectedIntSlice)
+ }
+
+ if !StrsEquals(parsedStringSlice, expectedStringSlice) {
+ t.Errorf("%v does not match %v", parsedStringSlice, expectedStringSlice)
+ }
+}
+
+func TestApp_BeforeFunc(t *testing.T) {
+ beforeRun, subcommandRun := false, false
+ beforeError := fmt.Errorf("fail")
+ var err error
+
+ app := cli.NewApp()
+
+ app.Before = func(c *cli.Context) error {
+ beforeRun = true
+ s := c.String("opt")
+ if s == "fail" {
+ return beforeError
+ }
+
+ return nil
+ }
+
+ app.Commands = []cli.Command{
+ cli.Command{
+ Name: "sub",
+ Action: func(c *cli.Context) {
+ subcommandRun = true
+ },
+ },
+ }
+
+ app.Flags = []cli.Flag{
+ cli.StringFlag{Name: "opt"},
+ }
+
+ // run with the Before() func succeeding
+ err = app.Run([]string{"command", "--opt", "succeed", "sub"})
+
+ if err != nil {
+ t.Fatalf("Run error: %s", err)
+ }
+
+ if beforeRun == false {
+ t.Errorf("Before() not executed when expected")
+ }
+
+ if subcommandRun == false {
+ t.Errorf("Subcommand not executed when expected")
+ }
+
+ // reset
+ beforeRun, subcommandRun = false, false
+
+ // run with the Before() func failing
+ err = app.Run([]string{"command", "--opt", "fail", "sub"})
+
+ // should be the same error produced by the Before func
+ if err != beforeError {
+ t.Errorf("Run error expected, but not received")
+ }
+
+ if beforeRun == false {
+ t.Errorf("Before() not executed when expected")
+ }
+
+ if subcommandRun == true {
+ t.Errorf("Subcommand executed when NOT expected")
+ }
+
+}
+
+func TestAppHelpPrinter(t *testing.T) {
+ oldPrinter := cli.HelpPrinter
+ defer func() {
+ cli.HelpPrinter = oldPrinter
+ }()
+
+ var wasCalled = false
+ cli.HelpPrinter = func(template string, data interface{}) {
+ wasCalled = true
+ }
+
+ app := cli.NewApp()
+ app.Run([]string{"-h"})
+
+ if wasCalled == false {
+ t.Errorf("Help printer expected to be called, but was not")
+ }
+}
+
+func TestAppCommandNotFound(t *testing.T) {
+ beforeRun, subcommandRun := false, false
+ app := cli.NewApp()
+
+ app.CommandNotFound = func(c *cli.Context, command string) {
+ beforeRun = true
+ }
+
+ app.Commands = []cli.Command{
+ cli.Command{
+ Name: "bar",
+ Action: func(c *cli.Context) {
+ subcommandRun = true
+ },
+ },
+ }
+
+ app.Run([]string{"command", "foo"})
+
+ expect(t, beforeRun, true)
+ expect(t, subcommandRun, false)
+}
+
+func TestGlobalFlagsInSubcommands(t *testing.T) {
+ subcommandRun := false
+ app := cli.NewApp()
+
+ app.Flags = []cli.Flag{
+ cli.BoolFlag{Name: "debug, d", Usage: "Enable debugging"},
+ }
+
+ app.Commands = []cli.Command{
+ cli.Command{
+ Name: "foo",
+ Subcommands: []cli.Command{
+ {
+ Name: "bar",
+ Action: func(c *cli.Context) {
+ if c.GlobalBool("debug") {
+ subcommandRun = true
+ }
+ },
+ },
+ },
+ },
+ }
+
+ app.Run([]string{"command", "-d", "foo", "bar"})
+
+ expect(t, subcommandRun, true)
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete
new file mode 100644
index 00000000..a860e038
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete
@@ -0,0 +1,13 @@
+#! /bin/bash
+
+_cli_bash_autocomplete() {
+ local cur prev opts base
+ COMPREPLY=()
+ cur="${COMP_WORDS[COMP_CWORD]}"
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
+ opts=$( ${COMP_WORDS[@]:0:COMP_CWORD} --generate-bash-completion )
+ COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
+ return 0
+ }
+
+ complete -F _cli_bash_autocomplete $PROG
\ No newline at end of file
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/cli.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/cli.go
new file mode 100644
index 00000000..b7425458
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/cli.go
@@ -0,0 +1,19 @@
+// 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
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/cli_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/cli_test.go
new file mode 100644
index 00000000..4d7bd847
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/cli_test.go
@@ -0,0 +1,88 @@
+package cli_test
+
+import (
+ "os"
+
+ "github.com/codegangsta/cli"
+)
+
+func Example() {
+ app := cli.NewApp()
+ app.Name = "todo"
+ app.Usage = "task list on the command line"
+ app.Commands = []cli.Command{
+ {
+ Name: "add",
+ ShortName: "a",
+ Usage: "add a task to the list",
+ Action: func(c *cli.Context) {
+ println("added task: ", c.Args().First())
+ },
+ },
+ {
+ Name: "complete",
+ ShortName: "c",
+ Usage: "complete a task on the list",
+ Action: func(c *cli.Context) {
+ println("completed task: ", c.Args().First())
+ },
+ },
+ }
+
+ app.Run(os.Args)
+}
+
+func ExampleSubcommand() {
+ app := cli.NewApp()
+ app.Name = "say"
+ app.Commands = []cli.Command{
+ {
+ Name: "hello",
+ ShortName: "hi",
+ Usage: "use it to see a description",
+ Description: "This is how we describe hello the function",
+ Subcommands: []cli.Command{
+ {
+ Name: "english",
+ ShortName: "en",
+ Usage: "sends a greeting in english",
+ Description: "greets someone in english",
+ Flags: []cli.Flag{
+ cli.StringFlag{Name: "name", Value: "Bob", Usage: "Name of the person to greet"},
+ },
+ Action: func(c *cli.Context) {
+ println("Hello, ", c.String("name"))
+ },
+ }, {
+ Name: "spanish",
+ ShortName: "sp",
+ Usage: "sends a greeting in spanish",
+ Flags: []cli.Flag{
+ cli.StringFlag{Name: "surname", Value: "Jones", Usage: "Surname of the person to greet"},
+ },
+ Action: func(c *cli.Context) {
+ println("Hola, ", c.String("surname"))
+ },
+ }, {
+ Name: "french",
+ ShortName: "fr",
+ Usage: "sends a greeting in french",
+ Flags: []cli.Flag{
+ cli.StringFlag{Name: "nickname", Value: "Stevie", Usage: "Nickname of the person to greet"},
+ },
+ Action: func(c *cli.Context) {
+ println("Bonjour, ", c.String("nickname"))
+ },
+ },
+ },
+ }, {
+ Name: "bye",
+ Usage: "says goodbye",
+ Action: func(c *cli.Context) {
+ println("bye")
+ },
+ },
+ }
+
+ app.Run(os.Args)
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/command.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/command.go
new file mode 100644
index 00000000..dcc8de5c
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/command.go
@@ -0,0 +1,141 @@
+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
+ ShortName string
+ // A short description of the usage of this command
+ Usage string
+ // A longer explanation of how the command works
+ Description 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
+ // 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
+}
+
+// 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 {
+ return c.startApp(ctx)
+ }
+
+ if !c.HideHelp {
+ // 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)
+
+ firstFlagIndex := -1
+ for index, arg := range ctx.Args() {
+ if strings.HasPrefix(arg, "-") {
+ firstFlagIndex = index
+ break
+ }
+ }
+
+ var err error
+ if firstFlagIndex > -1 && !c.SkipFlagParsing {
+ args := ctx.Args()
+ regularArgs := args[1:firstFlagIndex]
+ flagArgs := args[firstFlagIndex:]
+ err = set.Parse(append(flagArgs, regularArgs...))
+ } else {
+ err = set.Parse(ctx.Args().Tail())
+ }
+
+ if err != nil {
+ fmt.Printf("Incorrect Usage.\n\n")
+ ShowCommandHelp(ctx, c.Name)
+ fmt.Println("")
+ return err
+ }
+
+ nerr := normalizeFlags(c.Flags, set)
+ if nerr != nil {
+ fmt.Println(nerr)
+ fmt.Println("")
+ ShowCommandHelp(ctx, c.Name)
+ fmt.Println("")
+ return nerr
+ }
+ context := NewContext(ctx.App, set, ctx.globalSet)
+
+ if checkCommandCompletions(context, c.Name) {
+ return nil
+ }
+
+ if checkCommandHelp(context, c.Name) {
+ return nil
+ }
+ context.Command = c
+ c.Action(context)
+ return nil
+}
+
+// Returns true if Command.Name or Command.ShortName matches given name
+func (c Command) HasName(name string) bool {
+ return c.Name == name || c.ShortName == name
+}
+
+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.Description != "" {
+ app.Usage = c.Description
+ } else {
+ app.Usage = c.Usage
+ }
+
+ // set the flags and commands
+ app.Commands = c.Subcommands
+ app.Flags = c.Flags
+ app.HideHelp = c.HideHelp
+
+ // bash completion
+ app.EnableBashCompletion = ctx.App.EnableBashCompletion
+ if c.BashComplete != nil {
+ app.BashComplete = c.BashComplete
+ }
+
+ // set the actions
+ app.Before = c.Before
+ if c.Action != nil {
+ app.Action = c.Action
+ } else {
+ app.Action = helpSubcommand.Action
+ }
+
+ return app.RunAsSubcommand(ctx)
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/command_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/command_test.go
new file mode 100644
index 00000000..3afd83e7
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/command_test.go
@@ -0,0 +1,48 @@
+package cli_test
+
+import (
+ "flag"
+ "github.com/codegangsta/cli"
+ "testing"
+)
+
+func TestCommandDoNotIgnoreFlags(t *testing.T) {
+ app := cli.NewApp()
+ set := flag.NewFlagSet("test", 0)
+ test := []string{"blah", "blah", "-break"}
+ set.Parse(test)
+
+ c := cli.NewContext(app, set, set)
+
+ command := cli.Command {
+ Name: "test-cmd",
+ ShortName: "tc",
+ Usage: "this is for testing",
+ Description: "testing",
+ Action: func(_ *cli.Context) { },
+ }
+ err := command.Run(c)
+
+ expect(t, err.Error(), "flag provided but not defined: -break")
+}
+
+func TestCommandIgnoreFlags(t *testing.T) {
+ app := cli.NewApp()
+ set := flag.NewFlagSet("test", 0)
+ test := []string{"blah", "blah"}
+ set.Parse(test)
+
+ c := cli.NewContext(app, set, set)
+
+ command := cli.Command {
+ Name: "test-cmd",
+ ShortName: "tc",
+ Usage: "this is for testing",
+ Description: "testing",
+ Action: func(_ *cli.Context) { },
+ SkipFlagParsing: true,
+ }
+ err := command.Run(c)
+
+ expect(t, err, nil)
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/context.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/context.go
new file mode 100644
index 00000000..1e023cef
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/context.go
@@ -0,0 +1,280 @@
+package cli
+
+import (
+ "errors"
+ "flag"
+ "strconv"
+ "strings"
+)
+
+// 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
+ globalSet *flag.FlagSet
+ setFlags map[string]bool
+}
+
+// Creates a new context. For use in when invoking an App or Command action.
+func NewContext(app *App, set *flag.FlagSet, globalSet *flag.FlagSet) *Context {
+ return &Context{App: app, flagSet: set, globalSet: globalSet}
+}
+
+// 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 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 {
+ return lookupInt(name, c.globalSet)
+}
+
+// Looks up the value of a global bool flag, returns false if no bool flag exists
+func (c *Context) GlobalBool(name string) bool {
+ return lookupBool(name, c.globalSet)
+}
+
+// Looks up the value of a global string flag, returns "" if no string flag exists
+func (c *Context) GlobalString(name string) string {
+ return lookupString(name, c.globalSet)
+}
+
+// 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 {
+ return lookupStringSlice(name, c.globalSet)
+}
+
+// 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 {
+ return lookupIntSlice(name, c.globalSet)
+}
+
+// Looks up the value of a global generic flag, returns nil if no generic flag exists
+func (c *Context) GlobalGeneric(name string) interface{} {
+ return lookupGeneric(name, c.globalSet)
+}
+
+// Determines if the flag was actually set exists
+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
+}
+
+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 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 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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/context_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/context_test.go
new file mode 100644
index 00000000..89041b99
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/context_test.go
@@ -0,0 +1,68 @@
+package cli_test
+
+import (
+ "flag"
+ "github.com/codegangsta/cli"
+ "testing"
+)
+
+func TestNewContext(t *testing.T) {
+ set := flag.NewFlagSet("test", 0)
+ set.Int("myflag", 12, "doc")
+ globalSet := flag.NewFlagSet("test", 0)
+ globalSet.Int("myflag", 42, "doc")
+ command := cli.Command{Name: "mycommand"}
+ c := cli.NewContext(nil, set, globalSet)
+ c.Command = command
+ expect(t, c.Int("myflag"), 12)
+ expect(t, c.GlobalInt("myflag"), 42)
+ expect(t, c.Command.Name, "mycommand")
+}
+
+func TestContext_Int(t *testing.T) {
+ set := flag.NewFlagSet("test", 0)
+ set.Int("myflag", 12, "doc")
+ c := cli.NewContext(nil, set, set)
+ expect(t, c.Int("myflag"), 12)
+}
+
+func TestContext_String(t *testing.T) {
+ set := flag.NewFlagSet("test", 0)
+ set.String("myflag", "hello world", "doc")
+ c := cli.NewContext(nil, set, set)
+ expect(t, c.String("myflag"), "hello world")
+}
+
+func TestContext_Bool(t *testing.T) {
+ set := flag.NewFlagSet("test", 0)
+ set.Bool("myflag", false, "doc")
+ c := cli.NewContext(nil, set, set)
+ expect(t, c.Bool("myflag"), false)
+}
+
+func TestContext_BoolT(t *testing.T) {
+ set := flag.NewFlagSet("test", 0)
+ set.Bool("myflag", true, "doc")
+ c := cli.NewContext(nil, set, set)
+ expect(t, c.BoolT("myflag"), true)
+}
+
+func TestContext_Args(t *testing.T) {
+ set := flag.NewFlagSet("test", 0)
+ set.Bool("myflag", false, "doc")
+ c := cli.NewContext(nil, set, set)
+ set.Parse([]string{"--myflag", "bat", "baz"})
+ expect(t, len(c.Args()), 2)
+ expect(t, c.Bool("myflag"), true)
+}
+
+func TestContext_IsSet(t *testing.T) {
+ set := flag.NewFlagSet("test", 0)
+ set.Bool("myflag", false, "doc")
+ set.String("otherflag", "hello world", "doc")
+ c := cli.NewContext(nil, set, set)
+ set.Parse([]string{"--myflag", "bat", "baz"})
+ expect(t, c.IsSet("myflag"), true)
+ expect(t, c.IsSet("otherflag"), false)
+ expect(t, c.IsSet("bogusflag"), false)
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/flag.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/flag.go
new file mode 100644
index 00000000..e6f8838a
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/flag.go
@@ -0,0 +1,280 @@
+package cli
+
+import (
+ "flag"
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+// This flag enables bash-completion for all commands and subcommands
+var BashCompletionFlag = BoolFlag{"generate-bash-completion", ""}
+
+// This flag prints the version for the application
+var VersionFlag = BoolFlag{"version, v", "print the version"}
+
+// This flag prints the help for all commands and subcommands
+var HelpFlag = BoolFlag{"help, h", "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
+}
+
+func (f GenericFlag) String() string {
+ return fmt.Sprintf("%s%s %v\t`%v` %s", prefixFor(f.Name), f.Name, f.Value, "-"+f.Name+" option -"+f.Name+" option", f.Usage)
+}
+
+func (f GenericFlag) Apply(set *flag.FlagSet) {
+ eachName(f.Name, func(name string) {
+ set.Var(f.Value, name, f.Usage)
+ })
+}
+
+func (f GenericFlag) getName() string {
+ return f.Name
+}
+
+type StringSlice []string
+
+func (f *StringSlice) Set(value string) error {
+ *f = append(*f, value)
+ return nil
+}
+
+func (f *StringSlice) String() string {
+ return fmt.Sprintf("%s", *f)
+}
+
+func (f *StringSlice) Value() []string {
+ return *f
+}
+
+type StringSliceFlag struct {
+ Name string
+ Value *StringSlice
+ Usage string
+}
+
+func (f StringSliceFlag) String() string {
+ firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
+ pref := prefixFor(firstName)
+ return fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage)
+}
+
+func (f StringSliceFlag) Apply(set *flag.FlagSet) {
+ eachName(f.Name, func(name string) {
+ set.Var(f.Value, name, f.Usage)
+ })
+}
+
+func (f StringSliceFlag) getName() string {
+ return f.Name
+}
+
+type IntSlice []int
+
+func (f *IntSlice) Set(value string) error {
+
+ tmp, err := strconv.Atoi(value)
+ if err != nil {
+ return err
+ } else {
+ *f = append(*f, tmp)
+ }
+ return nil
+}
+
+func (f *IntSlice) String() string {
+ return fmt.Sprintf("%d", *f)
+}
+
+func (f *IntSlice) Value() []int {
+ return *f
+}
+
+type IntSliceFlag struct {
+ Name string
+ Value *IntSlice
+ Usage string
+}
+
+func (f IntSliceFlag) String() string {
+ firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
+ pref := prefixFor(firstName)
+ return fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage)
+}
+
+func (f IntSliceFlag) Apply(set *flag.FlagSet) {
+ eachName(f.Name, func(name string) {
+ set.Var(f.Value, name, f.Usage)
+ })
+}
+
+func (f IntSliceFlag) getName() string {
+ return f.Name
+}
+
+type BoolFlag struct {
+ Name string
+ Usage string
+}
+
+func (f BoolFlag) String() string {
+ return fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage)
+}
+
+func (f BoolFlag) Apply(set *flag.FlagSet) {
+ eachName(f.Name, func(name string) {
+ set.Bool(name, false, f.Usage)
+ })
+}
+
+func (f BoolFlag) getName() string {
+ return f.Name
+}
+
+type BoolTFlag struct {
+ Name string
+ Usage string
+}
+
+func (f BoolTFlag) String() string {
+ return fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage)
+}
+
+func (f BoolTFlag) Apply(set *flag.FlagSet) {
+ eachName(f.Name, func(name string) {
+ set.Bool(name, true, f.Usage)
+ })
+}
+
+func (f BoolTFlag) getName() string {
+ return f.Name
+}
+
+type StringFlag struct {
+ Name string
+ Value string
+ Usage string
+}
+
+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 fmt.Sprintf(fmtString, prefixedNames(f.Name), f.Value, f.Usage)
+}
+
+func (f StringFlag) Apply(set *flag.FlagSet) {
+ eachName(f.Name, func(name string) {
+ set.String(name, f.Value, f.Usage)
+ })
+}
+
+func (f StringFlag) getName() string {
+ return f.Name
+}
+
+type IntFlag struct {
+ Name string
+ Value int
+ Usage string
+}
+
+func (f IntFlag) String() string {
+ return fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), f.Value, f.Usage)
+}
+
+func (f IntFlag) Apply(set *flag.FlagSet) {
+ eachName(f.Name, func(name string) {
+ set.Int(name, f.Value, f.Usage)
+ })
+}
+
+func (f IntFlag) getName() string {
+ return f.Name
+}
+
+type Float64Flag struct {
+ Name string
+ Value float64
+ Usage string
+}
+
+func (f Float64Flag) String() string {
+ return fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), f.Value, f.Usage)
+}
+
+func (f Float64Flag) Apply(set *flag.FlagSet) {
+ eachName(f.Name, func(name string) {
+ 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
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/flag_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/flag_test.go
new file mode 100644
index 00000000..1c05f014
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/flag_test.go
@@ -0,0 +1,194 @@
+package cli_test
+
+import (
+ "github.com/codegangsta/cli"
+
+ "fmt"
+ "reflect"
+ "strings"
+ "testing"
+)
+
+var boolFlagTests = []struct {
+ name string
+ expected string
+}{
+ {"help", "--help\t"},
+ {"h", "-h\t"},
+}
+
+func TestBoolFlagHelpOutput(t *testing.T) {
+
+ for _, test := range boolFlagTests {
+ flag := cli.BoolFlag{Name: test.name}
+ output := flag.String()
+
+ if output != test.expected {
+ t.Errorf("%s does not match %s", output, test.expected)
+ }
+ }
+}
+
+var stringFlagTests = []struct {
+ name string
+ value string
+ expected string
+}{
+ {"help", "", "--help \t"},
+ {"h", "", "-h \t"},
+ {"h", "", "-h \t"},
+ {"test", "Something", "--test 'Something'\t"},
+}
+
+func TestStringFlagHelpOutput(t *testing.T) {
+
+ for _, test := range stringFlagTests {
+ flag := cli.StringFlag{Name: test.name, Value: test.value}
+ output := flag.String()
+
+ if output != test.expected {
+ t.Errorf("%s does not match %s", output, test.expected)
+ }
+ }
+}
+
+var intFlagTests = []struct {
+ name string
+ expected string
+}{
+ {"help", "--help '0'\t"},
+ {"h", "-h '0'\t"},
+}
+
+func TestIntFlagHelpOutput(t *testing.T) {
+
+ for _, test := range intFlagTests {
+ flag := cli.IntFlag{Name: test.name}
+ output := flag.String()
+
+ if output != test.expected {
+ t.Errorf("%s does not match %s", output, test.expected)
+ }
+ }
+}
+
+var float64FlagTests = []struct {
+ name string
+ expected string
+}{
+ {"help", "--help '0'\t"},
+ {"h", "-h '0'\t"},
+}
+
+func TestFloat64FlagHelpOutput(t *testing.T) {
+
+ for _, test := range float64FlagTests {
+ flag := cli.Float64Flag{Name: test.name}
+ output := flag.String()
+
+ if output != test.expected {
+ t.Errorf("%s does not match %s", output, test.expected)
+ }
+ }
+}
+
+func TestParseMultiString(t *testing.T) {
+ (&cli.App{
+ Flags: []cli.Flag{
+ cli.StringFlag{Name: "serve, s"},
+ },
+ Action: func(ctx *cli.Context) {
+ if ctx.String("serve") != "10" {
+ t.Errorf("main name not set")
+ }
+ if ctx.String("s") != "10" {
+ t.Errorf("short name not set")
+ }
+ },
+ }).Run([]string{"run", "-s", "10"})
+}
+
+func TestParseMultiStringSlice(t *testing.T) {
+ (&cli.App{
+ Flags: []cli.Flag{
+ cli.StringSliceFlag{Name: "serve, s", Value: &cli.StringSlice{}},
+ },
+ Action: func(ctx *cli.Context) {
+ if !reflect.DeepEqual(ctx.StringSlice("serve"), []string{"10", "20"}) {
+ t.Errorf("main name not set")
+ }
+ if !reflect.DeepEqual(ctx.StringSlice("s"), []string{"10", "20"}) {
+ t.Errorf("short name not set")
+ }
+ },
+ }).Run([]string{"run", "-s", "10", "-s", "20"})
+}
+
+func TestParseMultiInt(t *testing.T) {
+ a := cli.App{
+ Flags: []cli.Flag{
+ cli.IntFlag{Name: "serve, s"},
+ },
+ Action: func(ctx *cli.Context) {
+ if ctx.Int("serve") != 10 {
+ t.Errorf("main name not set")
+ }
+ if ctx.Int("s") != 10 {
+ t.Errorf("short name not set")
+ }
+ },
+ }
+ a.Run([]string{"run", "-s", "10"})
+}
+
+func TestParseMultiBool(t *testing.T) {
+ a := cli.App{
+ Flags: []cli.Flag{
+ cli.BoolFlag{Name: "serve, s"},
+ },
+ Action: func(ctx *cli.Context) {
+ if ctx.Bool("serve") != true {
+ t.Errorf("main name not set")
+ }
+ if ctx.Bool("s") != true {
+ t.Errorf("short name not set")
+ }
+ },
+ }
+ a.Run([]string{"run", "--serve"})
+}
+
+type Parser [2]string
+
+func (p *Parser) Set(value string) error {
+ parts := strings.Split(value, ",")
+ if len(parts) != 2 {
+ return fmt.Errorf("invalid format")
+ }
+
+ (*p)[0] = parts[0]
+ (*p)[1] = parts[1]
+
+ return nil
+}
+
+func (p *Parser) String() string {
+ return fmt.Sprintf("%s,%s", p[0], p[1])
+}
+
+func TestParseGeneric(t *testing.T) {
+ a := cli.App{
+ Flags: []cli.Flag{
+ cli.GenericFlag{Name: "serve, s", Value: &Parser{}},
+ },
+ Action: func(ctx *cli.Context) {
+ if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"10", "20"}) {
+ t.Errorf("main name not set")
+ }
+ if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"10", "20"}) {
+ t.Errorf("short name not set")
+ }
+ },
+ }
+ a.Run([]string{"run", "-s", "10,20"})
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/help.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/help.go
new file mode 100644
index 00000000..ccca0362
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/help.go
@@ -0,0 +1,213 @@
+package cli
+
+import (
+ "fmt"
+ "os"
+ "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:
+ {{.Name}} {{ if .Flags }}[global options] {{ end }}command{{ if .Flags }} [command options]{{ end }} [arguments...]
+
+VERSION:
+ {{.Version}}
+
+COMMANDS:
+ {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
+ {{end}}{{ if .Flags }}
+GLOBAL OPTIONS:
+ {{range .Flags}}{{.}}
+ {{end}}{{ 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:
+ {{.Name}} - {{.Usage}}
+
+USAGE:
+ command {{.Name}}{{ if .Flags }} [command options]{{ end }} [arguments...]
+
+DESCRIPTION:
+ {{.Description}}{{ 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:
+ {{.Name}} - {{.Usage}}
+
+USAGE:
+ {{.Name}} command{{ if .Flags }} [command options]{{ end }} [arguments...]
+
+COMMANDS:
+ {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
+ {{end}}{{ if .Flags }}
+OPTIONS:
+ {{range .Flags}}{{.}}
+ {{end}}{{ end }}
+`
+
+var helpCommand = Command{
+ Name: "help",
+ ShortName: "h",
+ Usage: "Shows a list of commands or help for one command",
+ Action: func(c *Context) {
+ args := c.Args()
+ if args.Present() {
+ ShowCommandHelp(c, args.First())
+ } else {
+ ShowAppHelp(c)
+ }
+ },
+}
+
+var helpSubcommand = Command{
+ Name: "help",
+ ShortName: "h",
+ Usage: "Shows a list of commands or help for one command",
+ Action: func(c *Context) {
+ args := c.Args()
+ if args.Present() {
+ ShowCommandHelp(c, args.First())
+ } else {
+ ShowSubcommandHelp(c)
+ }
+ },
+}
+
+// Prints help for the App
+var HelpPrinter = printHelp
+
+func ShowAppHelp(c *Context) {
+ HelpPrinter(AppHelpTemplate, c.App)
+}
+
+// Prints the list of subcommands as the default app completion method
+func DefaultAppComplete(c *Context) {
+ for _, command := range c.App.Commands {
+ fmt.Println(command.Name)
+ if command.ShortName != "" {
+ fmt.Println(command.ShortName)
+ }
+ }
+}
+
+// Prints help for the given command
+func ShowCommandHelp(c *Context, command string) {
+ for _, c := range c.App.Commands {
+ if c.HasName(command) {
+ HelpPrinter(CommandHelpTemplate, c)
+ return
+ }
+ }
+
+ if c.App.CommandNotFound != nil {
+ c.App.CommandNotFound(c, command)
+ } else {
+ fmt.Printf("No help topic for '%v'\n", command)
+ }
+}
+
+// Prints help for the given subcommand
+func ShowSubcommandHelp(c *Context) {
+ HelpPrinter(SubcommandHelpTemplate, c.App)
+}
+
+// Prints the version number of the App
+func ShowVersion(c *Context) {
+ fmt.Printf("%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(templ string, data interface{}) {
+ w := tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0)
+ t := template.Must(template.New("help").Parse(templ))
+ err := t.Execute(w, data)
+ if err != nil {
+ panic(err)
+ }
+ w.Flush()
+}
+
+func checkVersion(c *Context) bool {
+ if c.GlobalBool("version") {
+ ShowVersion(c)
+ return true
+ }
+
+ return false
+}
+
+func checkHelp(c *Context) bool {
+ if c.GlobalBool("h") || c.GlobalBool("help") {
+ ShowAppHelp(c)
+ return true
+ }
+
+ return false
+}
+
+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.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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/helpers_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/helpers_test.go
new file mode 100644
index 00000000..cdc4feb2
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/helpers_test.go
@@ -0,0 +1,19 @@
+package cli_test
+
+import (
+ "reflect"
+ "testing"
+)
+
+/* Test Helpers */
+func expect(t *testing.T, a interface{}, b interface{}) {
+ if a != b {
+ t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
+ }
+}
+
+func refute(t *testing.T, a interface{}, b interface{}) {
+ if a == b {
+ t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
+ }
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/.travis.yml b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/.travis.yml
new file mode 100644
index 00000000..8c9f56e4
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/.travis.yml
@@ -0,0 +1,8 @@
+language: go
+go: 1.2
+
+install:
+ - echo "Skip install"
+
+script:
+ - ./test
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/LICENSE b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/LICENSE
new file mode 100644
index 00000000..37ec93a1
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/LICENSE
@@ -0,0 +1,191 @@
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/README.md b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/README.md
new file mode 100644
index 00000000..0ee09fec
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/README.md
@@ -0,0 +1,44 @@
+# go-systemd
+
+Go bindings to systemd. The project has three packages:
+
+- activation - for writing and using socket activation from Go
+- journal - for writing to systemd's logging service, journal
+- dbus - for starting/stopping/inspecting running services and units
+
+Go docs for the entire project are here:
+
+http://godoc.org/github.com/coreos/go-systemd
+
+## Socket Activation
+
+An example HTTP server using socket activation can be quickly setup by
+following this README on a Linux machine running systemd:
+
+https://github.com/coreos/go-systemd/tree/master/examples/activation/httpserver
+
+## Journal
+
+Using this package you can submit journal entries directly to systemd's journal taking advantage of features like indexed key/value pairs for each log entry.
+
+## D-Bus
+
+The D-Bus API lets you start, stop and introspect systemd units. The API docs are here:
+
+http://godoc.org/github.com/coreos/go-systemd/dbus
+
+### Debugging
+
+Create `/etc/dbus-1/system-local.conf` that looks like this:
+
+```
+
+
+
+
+
+
+
+```
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/files.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/files.go
new file mode 100644
index 00000000..74b4fc10
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/files.go
@@ -0,0 +1,56 @@
+/*
+Copyright 2013 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 {
+ // there is no way to unset env in golang os package for now
+ // https://code.google.com/p/go/issues/detail?id=6423
+ defer os.Setenv("LISTEN_PID", "")
+ defer os.Setenv("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
+ }
+
+ var files []*os.File
+ 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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/files_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/files_test.go
new file mode 100644
index 00000000..a1c6948f
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/files_test.go
@@ -0,0 +1,84 @@
+/*
+Copyright 2013 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 (
+ "bytes"
+ "io"
+ "os"
+ "os/exec"
+ "testing"
+)
+
+// correctStringWritten fails the text if the correct string wasn't written
+// to the other side of the pipe.
+func correctStringWritten(t *testing.T, r *os.File, expected string) bool {
+ bytes := make([]byte, len(expected))
+ io.ReadAtLeast(r, bytes, len(expected))
+
+ if string(bytes) != expected {
+ t.Fatalf("Unexpected string %s", string(bytes))
+ }
+
+ return true
+}
+
+// TestActivation forks out a copy of activation.go example and reads back two
+// strings from the pipes that are passed in.
+func TestActivation(t *testing.T) {
+ cmd := exec.Command("go", "run", "../examples/activation/activation.go")
+
+ r1, w1, _ := os.Pipe()
+ r2, w2, _ := os.Pipe()
+ cmd.ExtraFiles = []*os.File{
+ w1,
+ w2,
+ }
+
+ cmd.Env = os.Environ()
+ cmd.Env = append(cmd.Env, "LISTEN_FDS=2", "FIX_LISTEN_PID=1")
+
+ err := cmd.Run()
+ if err != nil {
+ t.Fatalf(err.Error())
+ }
+
+ correctStringWritten(t, r1, "Hello world")
+ correctStringWritten(t, r2, "Goodbye world")
+}
+
+func TestActivationNoFix(t *testing.T) {
+ cmd := exec.Command("go", "run", "../examples/activation/activation.go")
+ cmd.Env = os.Environ()
+ cmd.Env = append(cmd.Env, "LISTEN_FDS=2")
+
+ out, _ := cmd.CombinedOutput()
+ if bytes.Contains(out, []byte("No files")) == false {
+ t.Fatalf("Child didn't error out as expected")
+ }
+}
+
+func TestActivationNoFiles(t *testing.T) {
+ cmd := exec.Command("go", "run", "../examples/activation/activation.go")
+ cmd.Env = os.Environ()
+ cmd.Env = append(cmd.Env, "LISTEN_FDS=0", "FIX_LISTEN_PID=1")
+
+ out, _ := cmd.CombinedOutput()
+ if bytes.Contains(out, []byte("No files")) == false {
+ t.Fatalf("Child didn't error out as expected")
+ }
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/listeners.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/listeners.go
new file mode 100644
index 00000000..cdb2cf4b
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/listeners.go
@@ -0,0 +1,38 @@
+/*
+Copyright 2014 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 (
+ "fmt"
+ "net"
+)
+
+// Listeners returns net.Listeners for all socket activated fds passed to this process.
+func Listeners(unsetEnv bool) ([]net.Listener, error) {
+ files := Files(unsetEnv)
+ listeners := make([]net.Listener, len(files))
+
+ for i, f := range files {
+ var err error
+ listeners[i], err = net.FileListener(f)
+ if err != nil {
+ return nil, fmt.Errorf("Error setting up FileListener for fd %d: %s", f.Fd(), err.Error())
+ }
+ }
+
+ return listeners, nil
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/listeners_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/listeners_test.go
new file mode 100644
index 00000000..c3627d6d
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/listeners_test.go
@@ -0,0 +1,88 @@
+/*
+Copyright 2014 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 (
+ "io"
+ "net"
+ "os"
+ "os/exec"
+ "testing"
+)
+
+// correctStringWritten fails the text if the correct string wasn't written
+// to the other side of the pipe.
+func correctStringWrittenNet(t *testing.T, r net.Conn, expected string) bool {
+ bytes := make([]byte, len(expected))
+ io.ReadAtLeast(r, bytes, len(expected))
+
+ if string(bytes) != expected {
+ t.Fatalf("Unexpected string %s", string(bytes))
+ }
+
+ return true
+}
+
+// TestActivation forks out a copy of activation.go example and reads back two
+// strings from the pipes that are passed in.
+func TestListeners(t *testing.T) {
+ cmd := exec.Command("go", "run", "../examples/activation/listen.go")
+
+ l1, err := net.Listen("tcp", ":9999")
+ if err != nil {
+ t.Fatalf(err.Error())
+ }
+ l2, err := net.Listen("tcp", ":1234")
+ if err != nil {
+ t.Fatalf(err.Error())
+ }
+
+ t1 := l1.(*net.TCPListener)
+ t2 := l2.(*net.TCPListener)
+
+ f1, _ := t1.File()
+ f2, _ := t2.File()
+
+ cmd.ExtraFiles = []*os.File{
+ f1,
+ f2,
+ }
+
+ r1, err := net.Dial("tcp", "127.0.0.1:9999")
+ if err != nil {
+ t.Fatalf(err.Error())
+ }
+ r1.Write([]byte("Hi"))
+
+ r2, err := net.Dial("tcp", "127.0.0.1:1234")
+ if err != nil {
+ t.Fatalf(err.Error())
+ }
+ r2.Write([]byte("Hi"))
+
+ cmd.Env = os.Environ()
+ cmd.Env = append(cmd.Env, "LISTEN_FDS=2", "FIX_LISTEN_PID=1")
+
+ out, err := cmd.Output()
+ if err != nil {
+ println(string(out))
+ t.Fatalf(err.Error())
+ }
+
+ correctStringWrittenNet(t, r1, "Hello world")
+ correctStringWrittenNet(t, r2, "Goodbye world")
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/dbus.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/dbus.go
new file mode 100644
index 00000000..91d71121
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/dbus.go
@@ -0,0 +1,104 @@
+/*
+Copyright 2013 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 (
+ "os"
+ "strconv"
+ "strings"
+ "sync"
+
+ "github.com/godbus/dbus"
+)
+
+const signalBuffer = 100
+
+// ObjectPath creates a dbus.ObjectPath using the rules that systemd uses for
+// serializing special characters.
+func ObjectPath(path string) dbus.ObjectPath {
+ path = strings.Replace(path, ".", "_2e", -1)
+ path = strings.Replace(path, "-", "_2d", -1)
+ path = strings.Replace(path, "@", "_40", -1)
+
+ return dbus.ObjectPath(path)
+}
+
+// Conn is a connection to systemds dbus endpoint.
+type Conn struct {
+ sysconn *dbus.Conn
+ sysobj *dbus.Object
+ 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
+ }
+ dispatch map[string]func(dbus.Signal)
+}
+
+// New() establishes a connection to the system bus and authenticates.
+func New() (*Conn, error) {
+ c := new(Conn)
+
+ if err := c.initConnection(); err != nil {
+ return nil, err
+ }
+
+ c.initJobs()
+ return c, nil
+}
+
+func (c *Conn) initConnection() error {
+ var err error
+ c.sysconn, err = dbus.SystemBusPrivate()
+ if err != nil {
+ return 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 = c.sysconn.Auth(methods)
+ if err != nil {
+ c.sysconn.Close()
+ return err
+ }
+
+ err = c.sysconn.Hello()
+ if err != nil {
+ c.sysconn.Close()
+ return err
+ }
+
+ c.sysobj = c.sysconn.Object("org.freedesktop.systemd1", dbus.ObjectPath("/org/freedesktop/systemd1"))
+
+ // Setup the listeners on jobs so that we can get completions
+ c.sysconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0,
+ "type='signal', interface='org.freedesktop.systemd1.Manager', member='JobRemoved'")
+ c.initSubscription()
+ c.initDispatch()
+
+ return nil
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/dbus_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/dbus_test.go
new file mode 100644
index 00000000..2e80f73e
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/dbus_test.go
@@ -0,0 +1,41 @@
+/*
+Copyright 2013 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 (
+ "testing"
+)
+
+// TestObjectPath ensures path encoding of the systemd rules works.
+func TestObjectPath(t *testing.T) {
+ input := "/silly-path/to@a/unit..service"
+ output := ObjectPath(input)
+ expected := "/silly_2dpath/to_40a/unit_2e_2eservice"
+
+ if string(output) != expected {
+ t.Fatalf("Output '%s' did not match expected '%s'", output, expected)
+ }
+}
+
+// TestNew ensures that New() works without errors.
+func TestNew(t *testing.T) {
+ _, err := New()
+
+ if err != nil {
+ t.Fatal(err)
+ }
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/methods.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/methods.go
new file mode 100644
index 00000000..a60de059
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/methods.go
@@ -0,0 +1,396 @@
+/*
+Copyright 2013 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"
+ "github.com/godbus/dbus"
+)
+
+func (c *Conn) initJobs() {
+ c.jobListener.jobs = make(map[dbus.ObjectPath]chan string)
+}
+
+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(job string, args ...interface{}) (<-chan string, error) {
+ c.jobListener.Lock()
+ defer c.jobListener.Unlock()
+
+ ch := make(chan string, 1)
+ var path dbus.ObjectPath
+ err := c.sysobj.Call(job, 0, args...).Store(&path)
+ if err != nil {
+ return nil, err
+ }
+ c.jobListener.jobs[path] = ch
+ return ch, nil
+}
+
+func (c *Conn) runJob(job string, args ...interface{}) (string, error) {
+ respCh, err := c.startJob(job, args...)
+ if err != nil {
+ return "", err
+ }
+ return <-respCh, nil
+}
+
+// StartUnit enqeues 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.
+//
+// Result string: 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.
+func (c *Conn) StartUnit(name string, mode string) (string, error) {
+ return c.runJob("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) (string, error) {
+ return c.runJob("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) (string, error) {
+ return c.runJob("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) (string, error) {
+ return c.runJob("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) (string, error) {
+ return c.runJob("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) (string, error) {
+ return c.runJob("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) (string, error) {
+ return c.runJob("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) (string, error) {
+ return c.runJob("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()
+}
+
+// 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 := ObjectPath("/org/freedesktop/systemd1/unit/" + 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 := ObjectPath("/org/freedesktop/systemd1/unit/" + 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()
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/methods_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/methods_test.go
new file mode 100644
index 00000000..8c7ab93e
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/methods_test.go
@@ -0,0 +1,332 @@
+/*
+Copyright 2013 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 (
+ "fmt"
+ "math/rand"
+ "os"
+ "path/filepath"
+ "reflect"
+ "testing"
+
+ "github.com/godbus/dbus"
+)
+
+func setupConn(t *testing.T) *Conn {
+ conn, err := New()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ return conn
+}
+
+func findFixture(target string, t *testing.T) string {
+ abs, err := filepath.Abs("../fixtures/" + target)
+ if err != nil {
+ t.Fatal(err)
+ }
+ return abs
+}
+
+func setupUnit(target string, conn *Conn, t *testing.T) {
+ // Blindly stop the unit in case it is running
+ conn.StopUnit(target, "replace")
+
+ // Blindly remove the symlink in case it exists
+ targetRun := filepath.Join("/run/systemd/system/", target)
+ os.Remove(targetRun)
+}
+
+func linkUnit(target string, conn *Conn, t *testing.T) {
+ abs := findFixture(target, t)
+ fixture := []string{abs}
+
+ changes, err := conn.LinkUnitFiles(fixture, true, true)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if len(changes) < 1 {
+ t.Fatalf("Expected one change, got %v", changes)
+ }
+
+ runPath := filepath.Join("/run/systemd/system/", target)
+ if changes[0].Filename != runPath {
+ t.Fatal("Unexpected target filename")
+ }
+}
+
+// Ensure that basic unit starting and stopping works.
+func TestStartStopUnit(t *testing.T) {
+ target := "start-stop.service"
+ conn := setupConn(t)
+
+ setupUnit(target, conn, t)
+ linkUnit(target, conn, t)
+
+ // 2. Start the unit
+ job, err := conn.StartUnit(target, "replace")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if job != "done" {
+ t.Fatal("Job is not done:", job)
+ }
+
+ units, err := conn.ListUnits()
+
+ var unit *UnitStatus
+ for _, u := range units {
+ if u.Name == target {
+ unit = &u
+ }
+ }
+
+ if unit == nil {
+ t.Fatalf("Test unit not found in list")
+ }
+
+ if unit.ActiveState != "active" {
+ t.Fatalf("Test unit not active")
+ }
+
+ // 3. Stop the unit
+ job, err = conn.StopUnit(target, "replace")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ units, err = conn.ListUnits()
+
+ unit = nil
+ for _, u := range units {
+ if u.Name == target {
+ unit = &u
+ }
+ }
+
+ if unit != nil {
+ t.Fatalf("Test unit found in list, should be stopped")
+ }
+}
+
+// Enables a unit and then immediately tears it down
+func TestEnableDisableUnit(t *testing.T) {
+ target := "enable-disable.service"
+ conn := setupConn(t)
+
+ setupUnit(target, conn, t)
+ abs := findFixture(target, t)
+ runPath := filepath.Join("/run/systemd/system/", target)
+
+ // 1. Enable the unit
+ install, changes, err := conn.EnableUnitFiles([]string{abs}, true, true)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if install != false {
+ t.Fatal("Install was true")
+ }
+
+ if len(changes) < 1 {
+ t.Fatalf("Expected one change, got %v", changes)
+ }
+
+ if changes[0].Filename != runPath {
+ t.Fatal("Unexpected target filename")
+ }
+
+ // 2. Disable the unit
+ dChanges, err := conn.DisableUnitFiles([]string{abs}, true)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if len(dChanges) != 1 {
+ t.Fatalf("Changes should include the path, %v", dChanges)
+ }
+ if dChanges[0].Filename != runPath {
+ t.Fatalf("Change should include correct filename, %+v", dChanges[0])
+ }
+ if dChanges[0].Destination != "" {
+ t.Fatalf("Change destination should be empty, %+v", dChanges[0])
+ }
+}
+
+// TestGetUnitProperties reads the `-.mount` which should exist on all systemd
+// systems and ensures that one of its properties is valid.
+func TestGetUnitProperties(t *testing.T) {
+ conn := setupConn(t)
+
+ unit := "-.mount"
+
+ info, err := conn.GetUnitProperties(unit)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ names := info["Wants"].([]string)
+
+ if len(names) < 1 {
+ t.Fatal("/ is unwanted")
+ }
+
+ if names[0] != "system.slice" {
+ t.Fatal("unexpected wants for /")
+ }
+
+ prop, err := conn.GetUnitProperty(unit, "Wants")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if prop.Name != "Wants" {
+ t.Fatal("unexpected property name")
+ }
+
+ val := prop.Value.Value().([]string)
+ if !reflect.DeepEqual(val, names) {
+ t.Fatal("unexpected property value")
+ }
+}
+
+// TestGetUnitPropertiesRejectsInvalidName attempts to get the properties for a
+// unit with an invalid name. This test should be run with --test.timeout set,
+// as a fail will manifest as GetUnitProperties hanging indefinitely.
+func TestGetUnitPropertiesRejectsInvalidName(t *testing.T) {
+ conn := setupConn(t)
+
+ unit := "//invalid#$^/"
+
+ _, err := conn.GetUnitProperties(unit)
+ if err == nil {
+ t.Fatal("Expected an error, got nil")
+ }
+
+ _, err = conn.GetUnitProperty(unit, "Wants")
+ if err == nil {
+ t.Fatal("Expected an error, got nil")
+ }
+}
+
+// TestSetUnitProperties changes a cgroup setting on the `tmp.mount`
+// which should exist on all systemd systems and ensures that the
+// property was set.
+func TestSetUnitProperties(t *testing.T) {
+ conn := setupConn(t)
+
+ unit := "tmp.mount"
+
+ if err := conn.SetUnitProperties(unit, true, Property{"CPUShares", dbus.MakeVariant(uint64(1023))}); err != nil {
+ t.Fatal(err)
+ }
+
+ info, err := conn.GetUnitTypeProperties(unit, "Mount")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ value := info["CPUShares"].(uint64)
+ if value != 1023 {
+ t.Fatal("CPUShares of unit is not 1023:", value)
+ }
+}
+
+// Ensure that basic transient unit starting and stopping works.
+func TestStartStopTransientUnit(t *testing.T) {
+ conn := setupConn(t)
+
+ props := []Property{
+ PropExecStart([]string{"/bin/sleep", "400"}, false),
+ }
+ target := fmt.Sprintf("testing-transient-%d.service", rand.Int())
+
+ // Start the unit
+ job, err := conn.StartTransientUnit(target, "replace", props...)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if job != "done" {
+ t.Fatal("Job is not done:", job)
+ }
+
+ units, err := conn.ListUnits()
+
+ var unit *UnitStatus
+ for _, u := range units {
+ if u.Name == target {
+ unit = &u
+ }
+ }
+
+ if unit == nil {
+ t.Fatalf("Test unit not found in list")
+ }
+
+ if unit.ActiveState != "active" {
+ t.Fatalf("Test unit not active")
+ }
+
+ // 3. Stop the unit
+ job, err = conn.StopUnit(target, "replace")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ units, err = conn.ListUnits()
+
+ unit = nil
+ for _, u := range units {
+ if u.Name == target {
+ unit = &u
+ }
+ }
+
+ if unit != nil {
+ t.Fatalf("Test unit found in list, should be stopped")
+ }
+}
+
+func TestConnJobListener(t *testing.T) {
+ target := "start-stop.service"
+ conn := setupConn(t)
+
+ setupUnit(target, conn, t)
+ linkUnit(target, conn, t)
+
+ jobSize := len(conn.jobListener.jobs)
+
+ _, err := conn.StartUnit(target, "replace")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ _, err = conn.StopUnit(target, "replace")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ currentJobSize := len(conn.jobListener.jobs)
+ if jobSize != currentJobSize {
+ t.Fatal("JobListener jobs leaked")
+ }
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/properties.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/properties.go
new file mode 100644
index 00000000..a06ccda7
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/properties.go
@@ -0,0 +1,220 @@
+/*
+Copyright 2013 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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/set.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/set.go
new file mode 100644
index 00000000..45ad1fb3
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/set.go
@@ -0,0 +1,33 @@
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/set_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/set_test.go
new file mode 100644
index 00000000..c4435f88
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/set_test.go
@@ -0,0 +1,39 @@
+package dbus
+
+import (
+ "testing"
+)
+
+// TestBasicSetActions asserts that Add & Remove behavior is correct
+func TestBasicSetActions(t *testing.T) {
+ s := newSet()
+
+ if s.Contains("foo") {
+ t.Fatal("set should not contain 'foo'")
+ }
+
+ s.Add("foo")
+
+ if !s.Contains("foo") {
+ t.Fatal("set should contain 'foo'")
+ }
+
+ v := s.Values()
+ if len(v) != 1 {
+ t.Fatal("set.Values did not report correct number of values")
+ }
+ if v[0] != "foo" {
+ t.Fatal("set.Values did not report value")
+ }
+
+ s.Remove("foo")
+
+ if s.Contains("foo") {
+ t.Fatal("set should not contain 'foo'")
+ }
+
+ v = s.Values()
+ if len(v) != 0 {
+ t.Fatal("set.Values did not report correct number of values")
+ }
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription.go
new file mode 100644
index 00000000..fcd29b6e
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription.go
@@ -0,0 +1,251 @@
+/*
+Copyright 2013 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.sysconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0,
+ "type='signal',interface='org.freedesktop.systemd1.Manager',member='UnitNew'")
+ c.sysconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0,
+ "type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'")
+
+ err := c.sysobj.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.sysobj.Call("org.freedesktop.systemd1.Manager.Unsubscribe", 0).Store()
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (c *Conn) initSubscription() {
+ c.subscriber.ignore = make(map[dbus.ObjectPath]int64)
+}
+
+func (c *Conn) initDispatch() {
+ ch := make(chan *dbus.Signal, signalBuffer)
+
+ c.sysconn.Signal(ch)
+
+ go func() {
+ for {
+ signal, ok := <-ch
+ if !ok {
+ return
+ }
+
+ switch signal.Name {
+ case "org.freedesktop.systemd1.Manager.JobRemoved":
+ c.jobComplete(signal)
+
+ unitName := signal.Body[2].(string)
+ var unitPath dbus.ObjectPath
+ c.sysobj.Call("org.freedesktop.systemd1.Manager.GetUnit", 0, unitName).Store(&unitPath)
+ if unitPath != dbus.ObjectPath("") {
+ c.sendSubStateUpdate(unitPath)
+ }
+ case "org.freedesktop.systemd1.Manager.UnitNew":
+ c.sendSubStateUpdate(signal.Body[1].(dbus.ObjectPath))
+ case "org.freedesktop.DBus.Properties.PropertiesChanged":
+ if signal.Body[0].(string) == "org.freedesktop.systemd1.Unit" {
+ // we only care about SubState updates, which are a Unit property
+ c.sendSubStateUpdate(signal.Path)
+ }
+ }
+ }
+ }()
+}
+
+// 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.subscriber.updateCh == nil {
+ return
+ }
+
+ 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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_set.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_set.go
new file mode 100644
index 00000000..26257860
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_set.go
@@ -0,0 +1,32 @@
+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,
+ func(u1, u2 *UnitStatus) bool { return *u1 != *u2 },
+ func(unit string) bool { return s.filter(unit) },
+ )
+}
+
+// NewSubscriptionSet returns a new subscription set.
+func (conn *Conn) NewSubscriptionSet() (*SubscriptionSet) {
+ return &SubscriptionSet{newSet(), conn}
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_set_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_set_test.go
new file mode 100644
index 00000000..4ecd1537
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_set_test.go
@@ -0,0 +1,66 @@
+package dbus
+
+import (
+ "testing"
+ "time"
+)
+
+// TestSubscribeUnit exercises the basics of subscription of a particular unit.
+func TestSubscriptionSetUnit(t *testing.T) {
+ target := "subscribe-events-set.service"
+
+ conn, err := New()
+
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ err = conn.Subscribe()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ subSet := conn.NewSubscriptionSet()
+ evChan, errChan := subSet.Subscribe()
+
+ subSet.Add(target)
+ setupUnit(target, conn, t)
+ linkUnit(target, conn, t)
+
+ job, err := conn.StartUnit(target, "replace")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if job != "done" {
+ t.Fatal("Couldn't start", target)
+ }
+
+ timeout := make(chan bool, 1)
+ go func() {
+ time.Sleep(3 * time.Second)
+ close(timeout)
+ }()
+
+ for {
+ select {
+ case changes := <-evChan:
+ tCh, ok := changes[target]
+
+ if !ok {
+ t.Fatal("Unexpected event:", changes)
+ }
+
+ if tCh.ActiveState == "active" && tCh.Name == target {
+ goto success
+ }
+ case err = <-errChan:
+ t.Fatal(err)
+ case <-timeout:
+ t.Fatal("Reached timeout")
+ }
+ }
+
+success:
+ return
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_test.go
new file mode 100644
index 00000000..f2b5dfc2
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_test.go
@@ -0,0 +1,91 @@
+package dbus
+
+import (
+ "testing"
+ "time"
+)
+
+// TestSubscribe exercises the basics of subscription
+func TestSubscribe(t *testing.T) {
+ conn, err := New()
+
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ err = conn.Subscribe()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ err = conn.Unsubscribe()
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
+// TestSubscribeUnit exercises the basics of subscription of a particular unit.
+func TestSubscribeUnit(t *testing.T) {
+ target := "subscribe-events.service"
+
+ conn, err := New()
+
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ err = conn.Subscribe()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ err = conn.Unsubscribe()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ evChan, errChan := conn.SubscribeUnits(time.Second)
+
+ setupUnit(target, conn, t)
+ linkUnit(target, conn, t)
+
+ job, err := conn.StartUnit(target, "replace")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if job != "done" {
+ t.Fatal("Couldn't start", target)
+ }
+
+ timeout := make(chan bool, 1)
+ go func() {
+ time.Sleep(3 * time.Second)
+ close(timeout)
+ }()
+
+ for {
+ select {
+ case changes := <-evChan:
+ tCh, ok := changes[target]
+
+ // Just continue until we see our event.
+ if !ok {
+ continue
+ }
+
+ if tCh.ActiveState == "active" && tCh.Name == target {
+ goto success
+ }
+ case err = <-errChan:
+ t.Fatal(err)
+ case <-timeout:
+ t.Fatal("Reached timeout")
+ }
+ }
+
+success:
+ return
+}
+
+
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/activation.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/activation.go
new file mode 100644
index 00000000..b3cf70ed
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/activation.go
@@ -0,0 +1,44 @@
+// Activation example used by the activation unit tests.
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/coreos/go-systemd/activation"
+)
+
+func fixListenPid() {
+ if os.Getenv("FIX_LISTEN_PID") != "" {
+ // HACK: real systemd would set LISTEN_PID before exec'ing but
+ // this is too difficult in golang for the purpose of a test.
+ // Do not do this in real code.
+ os.Setenv("LISTEN_PID", fmt.Sprintf("%d", os.Getpid()))
+ }
+}
+
+func main() {
+ fixListenPid()
+
+ files := activation.Files(false)
+
+ if len(files) == 0 {
+ panic("No files")
+ }
+
+ if os.Getenv("LISTEN_PID") == "" || os.Getenv("LISTEN_FDS") == "" {
+ panic("Should not unset envs")
+ }
+
+ files = activation.Files(true)
+
+ if os.Getenv("LISTEN_PID") != "" || os.Getenv("LISTEN_FDS") != "" {
+ panic("Can not unset envs")
+ }
+
+ // Write out the expected strings to the two pipes
+ files[0].Write([]byte("Hello world"))
+ files[1].Write([]byte("Goodbye world"))
+
+ return
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md
new file mode 100644
index 00000000..a350cca5
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md
@@ -0,0 +1,19 @@
+## socket activated http server
+
+This is a simple example of using socket activation with systemd to serve a
+simple HTTP server on http://127.0.0.1:8076
+
+To try it out `go get` the httpserver and run it under the systemd-activate helper
+
+```
+export GOPATH=`pwd`
+go get github.com/coreos/go-systemd/examples/activation/httpserver
+sudo /usr/lib/systemd/systemd-activate -l 127.0.0.1:8076 ./bin/httpserver
+```
+
+Then curl the URL and you will notice that it starts up:
+
+```
+curl 127.0.0.1:8076
+hello socket activated world!
+```
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service
new file mode 100644
index 00000000..c8dea0f6
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Hello World HTTP
+Requires=network.target
+After=multi-user.target
+
+[Service]
+Type=simple
+ExecStart=/usr/local/bin/httpserver
+
+[Install]
+WantedBy=multi-user.target
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket
new file mode 100644
index 00000000..723ed7ed
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket
@@ -0,0 +1,5 @@
+[Socket]
+ListenStream=127.0.0.1:8076
+
+[Install]
+WantedBy=sockets.target
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go
new file mode 100644
index 00000000..380c325d
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go
@@ -0,0 +1,26 @@
+package main
+
+import (
+ "io"
+ "net/http"
+
+ "github.com/coreos/go-systemd/activation"
+)
+
+func HelloServer(w http.ResponseWriter, req *http.Request) {
+ io.WriteString(w, "hello socket activated world!\n")
+}
+
+func main() {
+ listeners, err := activation.Listeners(true)
+ if err != nil {
+ panic(err)
+ }
+
+ if len(listeners) != 1 {
+ panic("Unexpected number of socket activation fds")
+ }
+
+ http.HandleFunc("/", HelloServer)
+ http.Serve(listeners[0], nil)
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/listen.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/listen.go
new file mode 100644
index 00000000..5850a8b7
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/listen.go
@@ -0,0 +1,50 @@
+// Activation example used by the activation unit tests.
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/coreos/go-systemd/activation"
+)
+
+func fixListenPid() {
+ if os.Getenv("FIX_LISTEN_PID") != "" {
+ // HACK: real systemd would set LISTEN_PID before exec'ing but
+ // this is too difficult in golang for the purpose of a test.
+ // Do not do this in real code.
+ os.Setenv("LISTEN_PID", fmt.Sprintf("%d", os.Getpid()))
+ }
+}
+
+func main() {
+ fixListenPid()
+
+ listeners, _ := activation.Listeners(false)
+
+ if len(listeners) == 0 {
+ panic("No listeners")
+ }
+
+ if os.Getenv("LISTEN_PID") == "" || os.Getenv("LISTEN_FDS") == "" {
+ panic("Should not unset envs")
+ }
+
+ listeners, err := activation.Listeners(true)
+ if err != nil {
+ panic(err)
+ }
+
+ if os.Getenv("LISTEN_PID") != "" || os.Getenv("LISTEN_FDS") != "" {
+ panic("Can not unset envs")
+ }
+
+ c0, _ := listeners[0].Accept()
+ c1, _ := listeners[1].Accept()
+
+ // Write out the expected strings to the two pipes
+ c0.Write([]byte("Hello world"))
+ c1.Write([]byte("Goodbye world"))
+
+ return
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/enable-disable.service b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/enable-disable.service
new file mode 100644
index 00000000..74c94590
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/enable-disable.service
@@ -0,0 +1,5 @@
+[Unit]
+Description=enable disable test
+
+[Service]
+ExecStart=/bin/sleep 400
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/start-stop.service b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/start-stop.service
new file mode 100644
index 00000000..a1f8c367
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/start-stop.service
@@ -0,0 +1,5 @@
+[Unit]
+Description=start stop test
+
+[Service]
+ExecStart=/bin/sleep 400
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/subscribe-events-set.service b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/subscribe-events-set.service
new file mode 100644
index 00000000..a1f8c367
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/subscribe-events-set.service
@@ -0,0 +1,5 @@
+[Unit]
+Description=start stop test
+
+[Service]
+ExecStart=/bin/sleep 400
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/subscribe-events.service b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/subscribe-events.service
new file mode 100644
index 00000000..a1f8c367
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/subscribe-events.service
@@ -0,0 +1,5 @@
+[Unit]
+Description=start stop test
+
+[Service]
+ExecStart=/bin/sleep 400
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/journal/send.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/journal/send.go
new file mode 100644
index 00000000..b52e1209
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/journal/send.go
@@ -0,0 +1,168 @@
+/*
+Copyright 2013 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 journal provides write bindings to the systemd journal
+package journal
+
+import (
+ "bytes"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net"
+ "os"
+ "strconv"
+ "strings"
+ "syscall"
+)
+
+// Priority of a journal message
+type Priority int
+
+const (
+ PriEmerg Priority = iota
+ PriAlert
+ PriCrit
+ PriErr
+ PriWarning
+ PriNotice
+ PriInfo
+ PriDebug
+)
+
+var conn net.Conn
+
+func init() {
+ var err error
+ conn, err = net.Dial("unixgram", "/run/systemd/journal/socket")
+ if err != nil {
+ conn = nil
+ }
+}
+
+// Enabled returns true iff the systemd journal is available for logging
+func Enabled() bool {
+ return conn != nil
+}
+
+// Send a message to the systemd journal. vars is a map of journald fields to
+// values. Fields must be composed of uppercase letters, numbers, and
+// underscores, but must not start with an underscore. Within these
+// restrictions, any arbitrary field name may be used. Some names have special
+// significance: see the journalctl documentation
+// (http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html)
+// for more details. vars may be nil.
+func Send(message string, priority Priority, vars map[string]string) error {
+ if conn == nil {
+ return journalError("could not connect to journald socket")
+ }
+
+ data := new(bytes.Buffer)
+ appendVariable(data, "PRIORITY", strconv.Itoa(int(priority)))
+ appendVariable(data, "MESSAGE", message)
+ for k, v := range vars {
+ appendVariable(data, k, v)
+ }
+
+ _, err := io.Copy(conn, data)
+ if err != nil && isSocketSpaceError(err) {
+ file, err := tempFd()
+ if err != nil {
+ return journalError(err.Error())
+ }
+ _, err = io.Copy(file, data)
+ if err != nil {
+ return journalError(err.Error())
+ }
+
+ rights := syscall.UnixRights(int(file.Fd()))
+
+ /* this connection should always be a UnixConn, but better safe than sorry */
+ unixConn, ok := conn.(*net.UnixConn)
+ if !ok {
+ return journalError("can't send file through non-Unix connection")
+ }
+ unixConn.WriteMsgUnix([]byte{}, rights, nil)
+ } else if err != nil {
+ return journalError(err.Error())
+ }
+ return nil
+}
+
+func appendVariable(w io.Writer, name, value string) {
+ if !validVarName(name) {
+ journalError("variable name contains invalid character, ignoring")
+ }
+ if strings.ContainsRune(value, '\n') {
+ /* When the value contains a newline, we write:
+ * - the variable name, followed by a newline
+ * - the size (in 64bit little endian format)
+ * - the data, followed by a newline
+ */
+ fmt.Fprintln(w, name)
+ binary.Write(w, binary.LittleEndian, uint64(len(value)))
+ fmt.Fprintln(w, value)
+ } else {
+ /* just write the variable and value all on one line */
+ fmt.Fprintf(w, "%s=%s\n", name, value)
+ }
+}
+
+func validVarName(name string) bool {
+ /* The variable name must be in uppercase and consist only of characters,
+ * numbers and underscores, and may not begin with an underscore. (from the docs)
+ */
+
+ valid := name[0] != '_'
+ for _, c := range name {
+ valid = valid && ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_'
+ }
+ return valid
+}
+
+func isSocketSpaceError(err error) bool {
+ opErr, ok := err.(*net.OpError)
+ if !ok {
+ return false
+ }
+
+ sysErr, ok := opErr.Err.(syscall.Errno)
+ if !ok {
+ return false
+ }
+
+ return sysErr == syscall.EMSGSIZE || sysErr == syscall.ENOBUFS
+}
+
+func tempFd() (*os.File, error) {
+ file, err := ioutil.TempFile("/dev/shm/", "journal.XXXXX")
+ if err != nil {
+ return nil, err
+ }
+ syscall.Unlink(file.Name())
+ if err != nil {
+ return nil, err
+ }
+ return file, nil
+}
+
+func journalError(s string) error {
+ s = "journal error: " + s
+ fmt.Fprintln(os.Stderr, s)
+ return errors.New(s)
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/login1/dbus.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/login1/dbus.go
new file mode 100644
index 00000000..d00dd110
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/login1/dbus.go
@@ -0,0 +1,81 @@
+/*
+Copyright 2014 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 logind API. See http://www.freedesktop.org/wiki/Software/systemd/logind/
+package login1
+
+import (
+ "os"
+ "strconv"
+
+ "github.com/godbus/dbus"
+)
+
+const (
+ dbusInterface = "org.freedesktop.login1.Manager"
+ dbusPath = "/org/freedesktop/login1"
+)
+
+// Conn is a connection to systemds dbus endpoint.
+type Conn struct {
+ conn *dbus.Conn
+ object *dbus.Object
+}
+
+// New() establishes a connection to the system bus and authenticates.
+func New() (*Conn, error) {
+ c := new(Conn)
+
+ if err := c.initConnection(); err != nil {
+ return nil, err
+ }
+
+ return c, nil
+}
+
+func (c *Conn) initConnection() error {
+ var err error
+ c.conn, err = dbus.SystemBusPrivate()
+ if err != nil {
+ return 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 = c.conn.Auth(methods)
+ if err != nil {
+ c.conn.Close()
+ return err
+ }
+
+ err = c.conn.Hello()
+ if err != nil {
+ c.conn.Close()
+ return err
+ }
+
+ c.object = c.conn.Object("org.freedesktop.login1", dbus.ObjectPath(dbusPath))
+
+ return nil
+}
+
+// Reboot asks logind for a reboot optionally asking for auth.
+func (c *Conn) Reboot(askForAuth bool) {
+ c.object.Call(dbusInterface+".Reboot", 0, askForAuth)
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/login1/dbus_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/login1/dbus_test.go
new file mode 100644
index 00000000..4439d373
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/login1/dbus_test.go
@@ -0,0 +1,30 @@
+/*
+Copyright 2014 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 login1
+
+import (
+ "testing"
+)
+
+// TestNew ensures that New() works without errors.
+func TestNew(t *testing.T) {
+ _, err := New()
+
+ if err != nil {
+ t.Fatal(err)
+ }
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/test b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/test
new file mode 100644
index 00000000..6e043658
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/test
@@ -0,0 +1,3 @@
+#!/bin/sh -e
+
+go test -v ./...
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/LICENSE b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/LICENSE
new file mode 100644
index 00000000..06b252bc
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/LICENSE
@@ -0,0 +1,25 @@
+Copyright (c) 2013, Georg Reinke ()
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/README.markdown b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/README.markdown
new file mode 100644
index 00000000..3ab21166
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/README.markdown
@@ -0,0 +1,38 @@
+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.
+
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/auth.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/auth.go
new file mode 100644
index 00000000..98017b69
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/auth.go
@@ -0,0 +1,253 @@
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/auth_external.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/auth_external.go
new file mode 100644
index 00000000..7e376d3e
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/auth_external.go
@@ -0,0 +1,26 @@
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/auth_sha1.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/auth_sha1.go
new file mode 100644
index 00000000..df15b461
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/auth_sha1.go
@@ -0,0 +1,102 @@
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/call.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/call.go
new file mode 100644
index 00000000..1d2fbc7e
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/call.go
@@ -0,0 +1,147 @@
+package dbus
+
+import (
+ "errors"
+ "strings"
+)
+
+// 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...)
+}
+
+// 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
+}
+
+// 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
+}
+
+// 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}
+}
+
+// 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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn.go
new file mode 100644
index 00000000..75dd2265
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn.go
@@ -0,0 +1,601 @@
+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 *Object
+ 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]interface{}
+ 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]interface{})
+ 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() *Object {
+ 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()
+ 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" && member == "NameLost" &&
+ sender == "org.freedesktop.DBus" {
+
+ name, _ := msg.Body[0].(string)
+ conn.namesLck.Lock()
+ for i, v := range conn.names {
+ if v == name {
+ copy(conn.names[i:], conn.names[i+1:])
+ conn.names = conn.names[:len(conn.names)-1]
+ }
+ }
+ 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 {
+ // don't block trying to send a signal
+ select {
+ case ch <- signal:
+ default:
+ }
+ }
+ 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) *Object {
+ 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 (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
+}
+
+func getTransport(address string) (transport, error) {
+ var err error
+ var t transport
+
+ m := map[string]func(string) (transport, error){
+ "unix": newUnixTransport,
+ }
+ 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 := m[v[:i]]
+ if f == nil {
+ err = errors.New("dbus: invalid bus address (invalid or unsupported transport)")
+ }
+ 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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn_darwin.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn_darwin.go
new file mode 100644
index 00000000..b67bb1b8
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn_darwin.go
@@ -0,0 +1,21 @@
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn_other.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn_other.go
new file mode 100644
index 00000000..f74b8758
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn_other.go
@@ -0,0 +1,27 @@
+// +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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn_test.go
new file mode 100644
index 00000000..a2b14e8c
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn_test.go
@@ -0,0 +1,199 @@
+package dbus
+
+import "testing"
+
+func TestSessionBus(t *testing.T) {
+ _, err := SessionBus()
+ if err != nil {
+ t.Error(err)
+ }
+}
+
+func TestSystemBus(t *testing.T) {
+ _, err := SystemBus()
+ if err != nil {
+ t.Error(err)
+ }
+}
+
+func TestSend(t *testing.T) {
+ bus, err := SessionBus()
+ if err != nil {
+ t.Error(err)
+ }
+ ch := make(chan *Call, 1)
+ msg := &Message{
+ Type: TypeMethodCall,
+ Flags: 0,
+ Headers: map[HeaderField]Variant{
+ FieldDestination: MakeVariant(bus.Names()[0]),
+ FieldPath: MakeVariant(ObjectPath("/org/freedesktop/DBus")),
+ FieldInterface: MakeVariant("org.freedesktop.DBus.Peer"),
+ FieldMember: MakeVariant("Ping"),
+ },
+ }
+ call := bus.Send(msg, ch)
+ <-ch
+ if call.Err != nil {
+ t.Error(call.Err)
+ }
+}
+
+type server struct{}
+
+func (server) Double(i int64) (int64, *Error) {
+ return 2 * i, nil
+}
+
+func BenchmarkCall(b *testing.B) {
+ b.StopTimer()
+ var s string
+ bus, err := SessionBus()
+ if err != nil {
+ b.Fatal(err)
+ }
+ name := bus.Names()[0]
+ obj := bus.BusObject()
+ b.StartTimer()
+ for i := 0; i < b.N; i++ {
+ err := obj.Call("org.freedesktop.DBus.GetNameOwner", 0, name).Store(&s)
+ if err != nil {
+ b.Fatal(err)
+ }
+ if s != name {
+ b.Errorf("got %s, wanted %s", s, name)
+ }
+ }
+}
+
+func BenchmarkCallAsync(b *testing.B) {
+ b.StopTimer()
+ bus, err := SessionBus()
+ if err != nil {
+ b.Fatal(err)
+ }
+ name := bus.Names()[0]
+ obj := bus.BusObject()
+ c := make(chan *Call, 50)
+ done := make(chan struct{})
+ go func() {
+ for i := 0; i < b.N; i++ {
+ v := <-c
+ if v.Err != nil {
+ b.Error(v.Err)
+ }
+ s := v.Body[0].(string)
+ if s != name {
+ b.Errorf("got %s, wanted %s", s, name)
+ }
+ }
+ close(done)
+ }()
+ b.StartTimer()
+ for i := 0; i < b.N; i++ {
+ obj.Go("org.freedesktop.DBus.GetNameOwner", 0, c, name)
+ }
+ <-done
+}
+
+func BenchmarkServe(b *testing.B) {
+ b.StopTimer()
+ srv, err := SessionBus()
+ if err != nil {
+ b.Fatal(err)
+ }
+ cli, err := SessionBusPrivate()
+ if err != nil {
+ b.Fatal(err)
+ }
+ if err = cli.Auth(nil); err != nil {
+ b.Fatal(err)
+ }
+ if err = cli.Hello(); err != nil {
+ b.Fatal(err)
+ }
+ benchmarkServe(b, srv, cli)
+}
+
+func BenchmarkServeAsync(b *testing.B) {
+ b.StopTimer()
+ srv, err := SessionBus()
+ if err != nil {
+ b.Fatal(err)
+ }
+ cli, err := SessionBusPrivate()
+ if err != nil {
+ b.Fatal(err)
+ }
+ if err = cli.Auth(nil); err != nil {
+ b.Fatal(err)
+ }
+ if err = cli.Hello(); err != nil {
+ b.Fatal(err)
+ }
+ benchmarkServeAsync(b, srv, cli)
+}
+
+func BenchmarkServeSameConn(b *testing.B) {
+ b.StopTimer()
+ bus, err := SessionBus()
+ if err != nil {
+ b.Fatal(err)
+ }
+
+ benchmarkServe(b, bus, bus)
+}
+
+func BenchmarkServeSameConnAsync(b *testing.B) {
+ b.StopTimer()
+ bus, err := SessionBus()
+ if err != nil {
+ b.Fatal(err)
+ }
+
+ benchmarkServeAsync(b, bus, bus)
+}
+
+func benchmarkServe(b *testing.B, srv, cli *Conn) {
+ var r int64
+ var err error
+ dest := srv.Names()[0]
+ srv.Export(server{}, "/org/guelfey/DBus/Test", "org.guelfey.DBus.Test")
+ obj := cli.Object(dest, "/org/guelfey/DBus/Test")
+ b.StartTimer()
+ for i := 0; i < b.N; i++ {
+ err = obj.Call("org.guelfey.DBus.Test.Double", 0, int64(i)).Store(&r)
+ if err != nil {
+ b.Fatal(err)
+ }
+ if r != 2*int64(i) {
+ b.Errorf("got %d, wanted %d", r, 2*int64(i))
+ }
+ }
+}
+
+func benchmarkServeAsync(b *testing.B, srv, cli *Conn) {
+ dest := srv.Names()[0]
+ srv.Export(server{}, "/org/guelfey/DBus/Test", "org.guelfey.DBus.Test")
+ obj := cli.Object(dest, "/org/guelfey/DBus/Test")
+ c := make(chan *Call, 50)
+ done := make(chan struct{})
+ go func() {
+ for i := 0; i < b.N; i++ {
+ v := <-c
+ if v.Err != nil {
+ b.Fatal(v.Err)
+ }
+ i, r := v.Args[0].(int64), v.Body[0].(int64)
+ if 2*i != r {
+ b.Errorf("got %d, wanted %d", r, 2*i)
+ }
+ }
+ close(done)
+ }()
+ b.StartTimer()
+ for i := 0; i < b.N; i++ {
+ obj.Go("org.guelfey.DBus.Test.Double", 0, c, int64(i))
+ }
+ <-done
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/dbus.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/dbus.go
new file mode 100644
index 00000000..2ce68735
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/dbus.go
@@ -0,0 +1,258 @@
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/decoder.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/decoder.go
new file mode 100644
index 00000000..ef50dcab
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/decoder.go
@@ -0,0 +1,228 @@
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/doc.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/doc.go
new file mode 100644
index 00000000..deff554a
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/doc.go
@@ -0,0 +1,63 @@
+/*
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/encoder.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/encoder.go
new file mode 100644
index 00000000..f9d2f057
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/encoder.go
@@ -0,0 +1,179 @@
+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 {
+ enc := new(encoder)
+ enc.out = out
+ enc.order = order
+ return enc
+}
+
+// Aligns the next output to be on a multiple of n. Panics on write errors.
+func (enc *encoder) align(n int) {
+ if enc.pos%n != 0 {
+ newpos := (enc.pos + n - 1) & ^(n - 1)
+ empty := make([]byte, newpos-enc.pos)
+ if _, err := enc.out.Write(empty); err != nil {
+ panic(err)
+ }
+ enc.pos = newpos
+ }
+}
+
+// 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"))
+ }
+ var buf bytes.Buffer
+ bufenc := newEncoder(&buf, 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()
+ var buf bytes.Buffer
+ bufenc := newEncoder(&buf, 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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/examples_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/examples_test.go
new file mode 100644
index 00000000..0218ac55
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/examples_test.go
@@ -0,0 +1,50 @@
+package dbus
+
+import "fmt"
+
+func ExampleConn_Emit() {
+ conn, err := SessionBus()
+ if err != nil {
+ panic(err)
+ }
+
+ conn.Emit("/foo/bar", "foo.bar.Baz", uint32(0xDAEDBEEF))
+}
+
+func ExampleObject_Call() {
+ var list []string
+
+ conn, err := SessionBus()
+ if err != nil {
+ panic(err)
+ }
+
+ err = conn.BusObject().Call("org.freedesktop.DBus.ListNames", 0).Store(&list)
+ if err != nil {
+ panic(err)
+ }
+ for _, v := range list {
+ fmt.Println(v)
+ }
+}
+
+func ExampleObject_Go() {
+ conn, err := SessionBus()
+ if err != nil {
+ panic(err)
+ }
+
+ ch := make(chan *Call, 10)
+ conn.BusObject().Go("org.freedesktop.DBus.ListActivatableNames", 0, ch)
+ select {
+ case call := <-ch:
+ if call.Err != nil {
+ panic(err)
+ }
+ list := call.Body[0].([]string)
+ for _, v := range list {
+ fmt.Println(v)
+ }
+ // put some other cases here
+ }
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/export.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/export.go
new file mode 100644
index 00000000..1dd15915
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/export.go
@@ -0,0 +1,302 @@
+package dbus
+
+import (
+ "errors"
+ "reflect"
+ "strings"
+ "unicode"
+)
+
+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"},
+ }
+)
+
+// Sender is a type which can be used in exported methods to receive the message
+// sender.
+type Sender string
+
+func exportedMethod(v interface{}, name string) reflect.Value {
+ if v == nil {
+ return reflect.Value{}
+ }
+ m := reflect.ValueOf(v).MethodByName(name)
+ if !m.IsValid() {
+ return reflect.Value{}
+ }
+ t := m.Type()
+ if t.NumOut() == 0 ||
+ t.Out(t.NumOut()-1) != reflect.TypeOf(&errmsgInvalidArg) {
+
+ return reflect.Value{}
+ }
+ return m
+}
+
+// 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 || unicode.IsLower([]rune(name)[0]) {
+ conn.sendError(errmsgUnknownMethod, sender, serial)
+ }
+ var m reflect.Value
+ if hasIface {
+ conn.handlersLck.RLock()
+ obj, ok := conn.handlers[path]
+ if !ok {
+ conn.sendError(errmsgNoObject, sender, serial)
+ conn.handlersLck.RUnlock()
+ return
+ }
+ iface := obj[ifaceName]
+ conn.handlersLck.RUnlock()
+ m = exportedMethod(iface, name)
+ } else {
+ conn.handlersLck.RLock()
+ if _, ok := conn.handlers[path]; !ok {
+ conn.sendError(errmsgNoObject, sender, serial)
+ conn.handlersLck.RUnlock()
+ return
+ }
+ for _, v := range conn.handlers[path] {
+ m = exportedMethod(v, name)
+ if m.IsValid() {
+ break
+ }
+ }
+ conn.handlersLck.RUnlock()
+ }
+ 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 {
+ 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
+ }
+ params := make([]reflect.Value, len(pointers))
+ for i := 0; i < len(pointers); i++ {
+ params[i] = reflect.ValueOf(pointers[i]).Elem()
+ }
+ 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).
+//
+// 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 {
+ if !path.IsValid() {
+ return errors.New("dbus: invalid path name")
+ }
+ conn.handlersLck.Lock()
+ 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 _, ok := conn.handlers[path]; !ok {
+ conn.handlers[path] = make(map[string]interface{})
+ }
+ conn.handlers[path][iface] = v
+ conn.handlersLck.Unlock()
+ return nil
+}
+
+// ReleaseName calls org.freedesktop.DBus.ReleaseName. You should use only this
+// method to release a name (see below).
+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
+ }
+ if r == uint32(ReleaseNameReplyReleased) {
+ conn.namesLck.Lock()
+ for i, v := range conn.names {
+ if v == name {
+ copy(conn.names[i:], conn.names[i+1:])
+ conn.names = conn.names[:len(conn.names)-1]
+ }
+ }
+ conn.namesLck.Unlock()
+ }
+ return ReleaseNameReply(r), nil
+}
+
+// RequestName calls org.freedesktop.DBus.RequestName. You should use only this
+// method to request a name because package dbus needs to keep track of all
+// names that the connection has.
+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
+ }
+ if r == uint32(RequestNameReplyPrimaryOwner) {
+ conn.namesLck.Lock()
+ conn.names = append(conn.names, name)
+ conn.namesLck.Unlock()
+ }
+ 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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/homedir.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/homedir.go
new file mode 100644
index 00000000..0b745f93
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/homedir.go
@@ -0,0 +1,28 @@
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/homedir_dynamic.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/homedir_dynamic.go
new file mode 100644
index 00000000..2732081e
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/homedir_dynamic.go
@@ -0,0 +1,15 @@
+// +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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/homedir_static.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/homedir_static.go
new file mode 100644
index 00000000..b9d9cb55
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/homedir_static.go
@@ -0,0 +1,45 @@
+// +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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/introspect/call.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/introspect/call.go
new file mode 100644
index 00000000..4aca2ea6
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/introspect/call.go
@@ -0,0 +1,27 @@
+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.Object) (*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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/introspect/introspect.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/introspect/introspect.go
new file mode 100644
index 00000000..dafcdb8b
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/introspect/introspect.go
@@ -0,0 +1,80 @@
+// 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"},
+ },
+ },
+ },
+}
+
+// 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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/introspect/introspectable.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/introspect/introspectable.go
new file mode 100644
index 00000000..a2a965a3
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/introspect/introspectable.go
@@ -0,0 +1,74 @@
+package introspect
+
+import (
+ "encoding/xml"
+ "github.com/godbus/dbus"
+ "reflect"
+)
+
+// 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(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{"", nil}) {
+
+ 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() {
+ 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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/message.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/message.go
new file mode 100644
index 00000000..075d6e38
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/message.go
@@ -0,0 +1,346 @@
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/prop/prop.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/prop/prop.go
new file mode 100644
index 00000000..ed5bdf22
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/prop/prop.go
@@ -0,0 +1,264 @@
+// 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.Error{"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.Error{"org.freedesktop.DBus.Properties.Error.PropertyNotFound", nil}
+
+// ErrReadOnly is the error returned to peers trying to set a read-only
+// property.
+var ErrReadOnly = &dbus.Error{"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.Error{"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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/proto_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/proto_test.go
new file mode 100644
index 00000000..608a770d
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/proto_test.go
@@ -0,0 +1,369 @@
+package dbus
+
+import (
+ "bytes"
+ "encoding/binary"
+ "io/ioutil"
+ "math"
+ "reflect"
+ "testing"
+)
+
+var protoTests = []struct {
+ vs []interface{}
+ bigEndian []byte
+ littleEndian []byte
+}{
+ {
+ []interface{}{int32(0)},
+ []byte{0, 0, 0, 0},
+ []byte{0, 0, 0, 0},
+ },
+ {
+ []interface{}{true, false},
+ []byte{0, 0, 0, 1, 0, 0, 0, 0},
+ []byte{1, 0, 0, 0, 0, 0, 0, 0},
+ },
+ {
+ []interface{}{byte(0), uint16(12), int16(32), uint32(43)},
+ []byte{0, 0, 0, 12, 0, 32, 0, 0, 0, 0, 0, 43},
+ []byte{0, 0, 12, 0, 32, 0, 0, 0, 43, 0, 0, 0},
+ },
+ {
+ []interface{}{int64(-1), uint64(1<<64 - 1)},
+ bytes.Repeat([]byte{255}, 16),
+ bytes.Repeat([]byte{255}, 16),
+ },
+ {
+ []interface{}{math.Inf(+1)},
+ []byte{0x7f, 0xf0, 0, 0, 0, 0, 0, 0},
+ []byte{0, 0, 0, 0, 0, 0, 0xf0, 0x7f},
+ },
+ {
+ []interface{}{"foo"},
+ []byte{0, 0, 0, 3, 'f', 'o', 'o', 0},
+ []byte{3, 0, 0, 0, 'f', 'o', 'o', 0},
+ },
+ {
+ []interface{}{Signature{"ai"}},
+ []byte{2, 'a', 'i', 0},
+ []byte{2, 'a', 'i', 0},
+ },
+ {
+ []interface{}{[]int16{42, 256}},
+ []byte{0, 0, 0, 4, 0, 42, 1, 0},
+ []byte{4, 0, 0, 0, 42, 0, 0, 1},
+ },
+ {
+ []interface{}{MakeVariant("foo")},
+ []byte{1, 's', 0, 0, 0, 0, 0, 3, 'f', 'o', 'o', 0},
+ []byte{1, 's', 0, 0, 3, 0, 0, 0, 'f', 'o', 'o', 0},
+ },
+ {
+ []interface{}{MakeVariant(MakeVariant(Signature{"v"}))},
+ []byte{1, 'v', 0, 1, 'g', 0, 1, 'v', 0},
+ []byte{1, 'v', 0, 1, 'g', 0, 1, 'v', 0},
+ },
+ {
+ []interface{}{map[int32]bool{42: true}},
+ []byte{0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 1},
+ []byte{8, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 1, 0, 0, 0},
+ },
+ {
+ []interface{}{map[string]Variant{}, byte(42)},
+ []byte{0, 0, 0, 0, 0, 0, 0, 0, 42},
+ []byte{0, 0, 0, 0, 0, 0, 0, 0, 42},
+ },
+ {
+ []interface{}{[]uint64{}, byte(42)},
+ []byte{0, 0, 0, 0, 0, 0, 0, 0, 42},
+ []byte{0, 0, 0, 0, 0, 0, 0, 0, 42},
+ },
+}
+
+func TestProto(t *testing.T) {
+ for i, v := range protoTests {
+ buf := new(bytes.Buffer)
+ bigEnc := newEncoder(buf, binary.BigEndian)
+ bigEnc.Encode(v.vs...)
+ marshalled := buf.Bytes()
+ if bytes.Compare(marshalled, v.bigEndian) != 0 {
+ t.Errorf("test %d (marshal be): got '%v', but expected '%v'\n", i+1, marshalled,
+ v.bigEndian)
+ }
+ buf.Reset()
+ litEnc := newEncoder(buf, binary.LittleEndian)
+ litEnc.Encode(v.vs...)
+ marshalled = buf.Bytes()
+ if bytes.Compare(marshalled, v.littleEndian) != 0 {
+ t.Errorf("test %d (marshal le): got '%v', but expected '%v'\n", i+1, marshalled,
+ v.littleEndian)
+ }
+ unmarshalled := reflect.MakeSlice(reflect.TypeOf(v.vs),
+ 0, 0)
+ for i := range v.vs {
+ unmarshalled = reflect.Append(unmarshalled,
+ reflect.New(reflect.TypeOf(v.vs[i])))
+ }
+ bigDec := newDecoder(bytes.NewReader(v.bigEndian), binary.BigEndian)
+ vs, err := bigDec.Decode(SignatureOf(v.vs...))
+ if err != nil {
+ t.Errorf("test %d (unmarshal be): %s\n", i+1, err)
+ continue
+ }
+ if !reflect.DeepEqual(vs, v.vs) {
+ t.Errorf("test %d (unmarshal be): got %#v, but expected %#v\n", i+1, vs, v.vs)
+ }
+ litDec := newDecoder(bytes.NewReader(v.littleEndian), binary.LittleEndian)
+ vs, err = litDec.Decode(SignatureOf(v.vs...))
+ if err != nil {
+ t.Errorf("test %d (unmarshal le): %s\n", i+1, err)
+ continue
+ }
+ if !reflect.DeepEqual(vs, v.vs) {
+ t.Errorf("test %d (unmarshal le): got %#v, but expected %#v\n", i+1, vs, v.vs)
+ }
+
+ }
+}
+
+func TestProtoMap(t *testing.T) {
+ m := map[string]uint8{
+ "foo": 23,
+ "bar": 2,
+ }
+ var n map[string]uint8
+ buf := new(bytes.Buffer)
+ enc := newEncoder(buf, binary.LittleEndian)
+ enc.Encode(m)
+ dec := newDecoder(buf, binary.LittleEndian)
+ vs, err := dec.Decode(Signature{"a{sy}"})
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err = Store(vs, &n); err != nil {
+ t.Fatal(err)
+ }
+ if len(n) != 2 || n["foo"] != 23 || n["bar"] != 2 {
+ t.Error("got", n)
+ }
+}
+
+func TestProtoVariantStruct(t *testing.T) {
+ var variant Variant
+ v := MakeVariant(struct {
+ A int32
+ B int16
+ }{1, 2})
+ buf := new(bytes.Buffer)
+ enc := newEncoder(buf, binary.LittleEndian)
+ enc.Encode(v)
+ dec := newDecoder(buf, binary.LittleEndian)
+ vs, err := dec.Decode(Signature{"v"})
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err = Store(vs, &variant); err != nil {
+ t.Fatal(err)
+ }
+ sl := variant.Value().([]interface{})
+ v1, v2 := sl[0].(int32), sl[1].(int16)
+ if v1 != int32(1) {
+ t.Error("got", v1, "as first int")
+ }
+ if v2 != int16(2) {
+ t.Error("got", v2, "as second int")
+ }
+}
+
+func TestProtoStructTag(t *testing.T) {
+ type Bar struct {
+ A int32
+ B chan interface{} `dbus:"-"`
+ C int32
+ }
+ var bar1, bar2 Bar
+ bar1.A = 234
+ bar2.C = 345
+ buf := new(bytes.Buffer)
+ enc := newEncoder(buf, binary.LittleEndian)
+ enc.Encode(bar1)
+ dec := newDecoder(buf, binary.LittleEndian)
+ vs, err := dec.Decode(Signature{"(ii)"})
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err = Store(vs, &bar2); err != nil {
+ t.Fatal(err)
+ }
+ if bar1 != bar2 {
+ t.Error("struct tag test: got", bar2)
+ }
+}
+
+func TestProtoStoreStruct(t *testing.T) {
+ var foo struct {
+ A int32
+ B string
+ c chan interface{}
+ D interface{} `dbus:"-"`
+ }
+ src := []interface{}{[]interface{}{int32(42), "foo"}}
+ err := Store(src, &foo)
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestProtoStoreNestedStruct(t *testing.T) {
+ var foo struct {
+ A int32
+ B struct {
+ C string
+ D float64
+ }
+ }
+ src := []interface{}{
+ []interface{}{
+ int32(42),
+ []interface{}{
+ "foo",
+ 3.14,
+ },
+ },
+ }
+ err := Store(src, &foo)
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestMessage(t *testing.T) {
+ buf := new(bytes.Buffer)
+ message := new(Message)
+ message.Type = TypeMethodCall
+ message.serial = 32
+ message.Headers = map[HeaderField]Variant{
+ FieldPath: MakeVariant(ObjectPath("/org/foo/bar")),
+ FieldMember: MakeVariant("baz"),
+ }
+ message.Body = make([]interface{}, 0)
+ err := message.EncodeTo(buf, binary.LittleEndian)
+ if err != nil {
+ t.Error(err)
+ }
+ _, err = DecodeMessage(buf)
+ if err != nil {
+ t.Error(err)
+ }
+}
+
+func TestProtoStructInterfaces(t *testing.T) {
+ b := []byte{42}
+ vs, err := newDecoder(bytes.NewReader(b), binary.LittleEndian).Decode(Signature{"(y)"})
+ if err != nil {
+ t.Fatal(err)
+ }
+ if vs[0].([]interface{})[0].(byte) != 42 {
+ t.Errorf("wrongs results (got %v)", vs)
+ }
+}
+
+// ordinary org.freedesktop.DBus.Hello call
+var smallMessage = &Message{
+ Type: TypeMethodCall,
+ serial: 1,
+ Headers: map[HeaderField]Variant{
+ FieldDestination: MakeVariant("org.freedesktop.DBus"),
+ FieldPath: MakeVariant(ObjectPath("/org/freedesktop/DBus")),
+ FieldInterface: MakeVariant("org.freedesktop.DBus"),
+ FieldMember: MakeVariant("Hello"),
+ },
+}
+
+// org.freedesktop.Notifications.Notify
+var bigMessage = &Message{
+ Type: TypeMethodCall,
+ serial: 2,
+ Headers: map[HeaderField]Variant{
+ FieldDestination: MakeVariant("org.freedesktop.Notifications"),
+ FieldPath: MakeVariant(ObjectPath("/org/freedesktop/Notifications")),
+ FieldInterface: MakeVariant("org.freedesktop.Notifications"),
+ FieldMember: MakeVariant("Notify"),
+ FieldSignature: MakeVariant(Signature{"susssasa{sv}i"}),
+ },
+ Body: []interface{}{
+ "app_name",
+ uint32(0),
+ "dialog-information",
+ "Notification",
+ "This is the body of a notification",
+ []string{"ok", "Ok"},
+ map[string]Variant{
+ "sound-name": MakeVariant("dialog-information"),
+ },
+ int32(-1),
+ },
+}
+
+func BenchmarkDecodeMessageSmall(b *testing.B) {
+ var err error
+ var rd *bytes.Reader
+
+ b.StopTimer()
+ buf := new(bytes.Buffer)
+ err = smallMessage.EncodeTo(buf, binary.LittleEndian)
+ if err != nil {
+ b.Fatal(err)
+ }
+ decoded := buf.Bytes()
+ b.StartTimer()
+ for i := 0; i < b.N; i++ {
+ rd = bytes.NewReader(decoded)
+ _, err = DecodeMessage(rd)
+ if err != nil {
+ b.Fatal(err)
+ }
+ }
+}
+
+func BenchmarkDecodeMessageBig(b *testing.B) {
+ var err error
+ var rd *bytes.Reader
+
+ b.StopTimer()
+ buf := new(bytes.Buffer)
+ err = bigMessage.EncodeTo(buf, binary.LittleEndian)
+ if err != nil {
+ b.Fatal(err)
+ }
+ decoded := buf.Bytes()
+ b.StartTimer()
+ for i := 0; i < b.N; i++ {
+ rd = bytes.NewReader(decoded)
+ _, err = DecodeMessage(rd)
+ if err != nil {
+ b.Fatal(err)
+ }
+ }
+}
+
+func BenchmarkEncodeMessageSmall(b *testing.B) {
+ var err error
+ for i := 0; i < b.N; i++ {
+ err = smallMessage.EncodeTo(ioutil.Discard, binary.LittleEndian)
+ if err != nil {
+ b.Fatal(err)
+ }
+ }
+}
+
+func BenchmarkEncodeMessageBig(b *testing.B) {
+ var err error
+ for i := 0; i < b.N; i++ {
+ err = bigMessage.EncodeTo(ioutil.Discard, binary.LittleEndian)
+ if err != nil {
+ b.Fatal(err)
+ }
+ }
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/sig.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/sig.go
new file mode 100644
index 00000000..f45b53ce
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/sig.go
@@ -0,0 +1,257 @@
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/sig_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/sig_test.go
new file mode 100644
index 00000000..da37bc96
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/sig_test.go
@@ -0,0 +1,70 @@
+package dbus
+
+import (
+ "testing"
+)
+
+var sigTests = []struct {
+ vs []interface{}
+ sig Signature
+}{
+ {
+ []interface{}{new(int32)},
+ Signature{"i"},
+ },
+ {
+ []interface{}{new(string)},
+ Signature{"s"},
+ },
+ {
+ []interface{}{new(Signature)},
+ Signature{"g"},
+ },
+ {
+ []interface{}{new([]int16)},
+ Signature{"an"},
+ },
+ {
+ []interface{}{new(int16), new(uint32)},
+ Signature{"nu"},
+ },
+ {
+ []interface{}{new(map[byte]Variant)},
+ Signature{"a{yv}"},
+ },
+ {
+ []interface{}{new(Variant), new([]map[int32]string)},
+ Signature{"vaa{is}"},
+ },
+}
+
+func TestSig(t *testing.T) {
+ for i, v := range sigTests {
+ sig := SignatureOf(v.vs...)
+ if sig != v.sig {
+ t.Errorf("test %d: got %q, expected %q", i+1, sig.str, v.sig.str)
+ }
+ }
+}
+
+var getSigTest = []interface{}{
+ []struct {
+ b byte
+ i int32
+ t uint64
+ s string
+ }{},
+ map[string]Variant{},
+}
+
+func BenchmarkGetSignatureSimple(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ SignatureOf("", int32(0))
+ }
+}
+
+func BenchmarkGetSignatureLong(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ SignatureOf(getSigTest...)
+ }
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_darwin.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_darwin.go
new file mode 100644
index 00000000..1bba0d6b
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_darwin.go
@@ -0,0 +1,6 @@
+package dbus
+
+func (t *unixTransport) SendNullByte() error {
+ _, err := t.Write([]byte{0})
+ return err
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_generic.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_generic.go
new file mode 100644
index 00000000..46f8f49d
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_generic.go
@@ -0,0 +1,35 @@
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_unix.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_unix.go
new file mode 100644
index 00000000..d16229be
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_unix.go
@@ -0,0 +1,190 @@
+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 (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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_unix_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_unix_test.go
new file mode 100644
index 00000000..302233fc
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_unix_test.go
@@ -0,0 +1,49 @@
+package dbus
+
+import (
+ "os"
+ "testing"
+)
+
+const testString = `This is a test!
+This text should be read from the file that is created by this test.`
+
+type unixFDTest struct{}
+
+func (t unixFDTest) Test(fd UnixFD) (string, *Error) {
+ var b [4096]byte
+ file := os.NewFile(uintptr(fd), "testfile")
+ defer file.Close()
+ n, err := file.Read(b[:])
+ if err != nil {
+ return "", &Error{"com.github.guelfey.test.Error", nil}
+ }
+ return string(b[:n]), nil
+}
+
+func TestUnixFDs(t *testing.T) {
+ conn, err := SessionBus()
+ if err != nil {
+ t.Fatal(err)
+ }
+ r, w, err := os.Pipe()
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer w.Close()
+ if _, err := w.Write([]byte(testString)); err != nil {
+ t.Fatal(err)
+ }
+ name := conn.Names()[0]
+ test := unixFDTest{}
+ conn.Export(test, "/com/github/guelfey/test", "com.github.guelfey.test")
+ var s string
+ obj := conn.Object(name, "/com/github/guelfey/test")
+ err = obj.Call("com.github.guelfey.test.Test", 0, UnixFD(r.Fd())).Store(&s)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if s != testString {
+ t.Fatal("got", s, "wanted", testString)
+ }
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_unixcred.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_unixcred.go
new file mode 100644
index 00000000..42a0e769
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_unixcred.go
@@ -0,0 +1,22 @@
+// +build !darwin
+
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/variant.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/variant.go
new file mode 100644
index 00000000..b1b53ceb
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/variant.go
@@ -0,0 +1,129 @@
+package dbus
+
+import (
+ "bytes"
+ "fmt"
+ "reflect"
+ "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
+ buf := bytes.NewBuffer([]byte("{"))
+ for i, k := range rv.MapKeys() {
+ s, b := MakeVariant(k.Interface()).format()
+ unamb = unamb && b
+ buf.WriteString(s)
+ buf.WriteString(": ")
+ s, b = MakeVariant(rv.MapIndex(k).Interface()).format()
+ unamb = unamb && b
+ buf.WriteString(s)
+ if i != rv.Len()-1 {
+ buf.WriteString(", ")
+ }
+ }
+ 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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/variant_lexer.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/variant_lexer.go
new file mode 100644
index 00000000..332007d6
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/variant_lexer.go
@@ -0,0 +1,284 @@
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/variant_parser.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/variant_parser.go
new file mode 100644
index 00000000..d20f5da6
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/variant_parser.go
@@ -0,0 +1,817 @@
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/variant_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/variant_test.go
new file mode 100644
index 00000000..da917c8e
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/variant_test.go
@@ -0,0 +1,78 @@
+package dbus
+
+import "reflect"
+import "testing"
+
+var variantFormatTests = []struct {
+ v interface{}
+ s string
+}{
+ {int32(1), `1`},
+ {"foo", `"foo"`},
+ {ObjectPath("/org/foo"), `@o "/org/foo"`},
+ {Signature{"i"}, `@g "i"`},
+ {[]byte{}, `@ay []`},
+ {[]int32{1, 2}, `[1, 2]`},
+ {[]int64{1, 2}, `@ax [1, 2]`},
+ {[][]int32{{3, 4}, {5, 6}}, `[[3, 4], [5, 6]]`},
+ {[]Variant{MakeVariant(int32(1)), MakeVariant(1.0)}, `[<1>, <@d 1>]`},
+ {map[string]int32{"one": 1, "two": 2}, `{"one": 1, "two": 2}`},
+ {map[int32]ObjectPath{1: "/org/foo"}, `@a{io} {1: "/org/foo"}`},
+ {map[string]Variant{}, `@a{sv} {}`},
+}
+
+func TestFormatVariant(t *testing.T) {
+ for i, v := range variantFormatTests {
+ if s := MakeVariant(v.v).String(); s != v.s {
+ t.Errorf("test %d: got %q, wanted %q", i+1, s, v.s)
+ }
+ }
+}
+
+var variantParseTests = []struct {
+ s string
+ v interface{}
+}{
+ {"1", int32(1)},
+ {"true", true},
+ {"false", false},
+ {"1.0", float64(1.0)},
+ {"0x10", int32(16)},
+ {"1e1", float64(10)},
+ {`"foo"`, "foo"},
+ {`"\a\b\f\n\r\t"`, "\x07\x08\x0c\n\r\t"},
+ {`"\u00e4\U0001f603"`, "\u00e4\U0001f603"},
+ {"[1]", []int32{1}},
+ {"[1, 2, 3]", []int32{1, 2, 3}},
+ {"@ai []", []int32{}},
+ {"[1, 5.0]", []float64{1, 5.0}},
+ {"[[1, 2], [3, 4.0]]", [][]float64{{1, 2}, {3, 4}}},
+ {`[@o "/org/foo", "/org/bar"]`, []ObjectPath{"/org/foo", "/org/bar"}},
+ {"<1>", MakeVariant(int32(1))},
+ {"[<1>, <2.0>]", []Variant{MakeVariant(int32(1)), MakeVariant(2.0)}},
+ {`[[], [""]]`, [][]string{{}, {""}}},
+ {`@a{ss} {}`, map[string]string{}},
+ {`{"foo": 1}`, map[string]int32{"foo": 1}},
+ {`[{}, {"foo": "bar"}]`, []map[string]string{{}, {"foo": "bar"}}},
+ {`{"a": <1>, "b": <"foo">}`,
+ map[string]Variant{"a": MakeVariant(int32(1)), "b": MakeVariant("foo")}},
+ {`b''`, []byte{0}},
+ {`b"abc"`, []byte{'a', 'b', 'c', 0}},
+ {`b"\x01\0002\a\b\f\n\r\t"`, []byte{1, 2, 0x7, 0x8, 0xc, '\n', '\r', '\t', 0}},
+ {`[[0], b""]`, [][]byte{{0}, {0}}},
+ {"int16 0", int16(0)},
+ {"byte 0", byte(0)},
+}
+
+func TestParseVariant(t *testing.T) {
+ for i, v := range variantParseTests {
+ nv, err := ParseVariant(v.s, Signature{})
+ if err != nil {
+ t.Errorf("test %d: parsing failed: %s", i+1, err)
+ continue
+ }
+ if !reflect.DeepEqual(nv.value, v.v) {
+ t.Errorf("test %d: got %q, wanted %q", i+1, nv, v.v)
+ }
+ }
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/LICENSE b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/LICENSE
new file mode 100644
index 00000000..80dd96de
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/LICENSE
@@ -0,0 +1,24 @@
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/capability.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/capability.go
new file mode 100644
index 00000000..9df3b415
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/capability.go
@@ -0,0 +1,71 @@
+// 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.
+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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/capability_linux.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/capability_linux.go
new file mode 100644
index 00000000..c5f335f7
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/capability_linux.go
@@ -0,0 +1,566 @@
+// 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
+
+func init() {
+ var hdr capHeader
+ capget(&hdr, nil)
+ capVers = hdr.version
+}
+
+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
+ }
+
+ f, err := os.Open(fmt.Sprintf("/proc/%d/status", c.hdr.pid))
+ 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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/capability_noop.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/capability_noop.go
new file mode 100644
index 00000000..9bb3070c
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/capability_noop.go
@@ -0,0 +1,19 @@
+// 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/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/capability_test.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/capability_test.go
new file mode 100644
index 00000000..8108655c
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/capability_test.go
@@ -0,0 +1,83 @@
+// 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 "testing"
+
+func TestState(t *testing.T) {
+ testEmpty := func(name string, c Capabilities, whats CapType) {
+ for i := CapType(1); i <= BOUNDING; i <<= 1 {
+ if (i&whats) != 0 && !c.Empty(i) {
+ t.Errorf(name+": capabilities set %q wasn't empty", i)
+ }
+ }
+ }
+ testFull := func(name string, c Capabilities, whats CapType) {
+ for i := CapType(1); i <= BOUNDING; i <<= 1 {
+ if (i&whats) != 0 && !c.Full(i) {
+ t.Errorf(name+": capabilities set %q wasn't full", i)
+ }
+ }
+ }
+ testPartial := func(name string, c Capabilities, whats CapType) {
+ for i := CapType(1); i <= BOUNDING; i <<= 1 {
+ if (i&whats) != 0 && (c.Empty(i) || c.Full(i)) {
+ t.Errorf(name+": capabilities set %q wasn't partial", i)
+ }
+ }
+ }
+ testGet := func(name string, c Capabilities, whats CapType, max Cap) {
+ for i := CapType(1); i <= BOUNDING; i <<= 1 {
+ if (i & whats) == 0 {
+ continue
+ }
+ for j := Cap(0); j <= max; j++ {
+ if !c.Get(i, j) {
+ t.Errorf(name+": capability %q wasn't found on %q", j, i)
+ }
+ }
+ }
+ }
+
+ capf := new(capsFile)
+ capf.data.version = 2
+ for _, tc := range []struct {
+ name string
+ c Capabilities
+ sets CapType
+ max Cap
+ }{
+ {"v1", new(capsV1), EFFECTIVE | PERMITTED, CAP_AUDIT_CONTROL},
+ {"v3", new(capsV3), EFFECTIVE | PERMITTED | BOUNDING, CAP_LAST_CAP},
+ {"file_v1", new(capsFile), EFFECTIVE | PERMITTED, CAP_AUDIT_CONTROL},
+ {"file_v2", capf, EFFECTIVE | PERMITTED, CAP_LAST_CAP},
+ } {
+ testEmpty(tc.name, tc.c, tc.sets)
+ tc.c.Fill(CAPS | BOUNDS)
+ testFull(tc.name, tc.c, tc.sets)
+ testGet(tc.name, tc.c, tc.sets, tc.max)
+ tc.c.Clear(CAPS | BOUNDS)
+ testEmpty(tc.name, tc.c, tc.sets)
+ for i := CapType(1); i <= BOUNDING; i <<= 1 {
+ for j := Cap(0); j <= CAP_LAST_CAP; j++ {
+ tc.c.Set(i, j)
+ }
+ }
+ testFull(tc.name, tc.c, tc.sets)
+ testGet(tc.name, tc.c, tc.sets, tc.max)
+ for i := CapType(1); i <= BOUNDING; i <<= 1 {
+ for j := Cap(0); j <= CAP_LAST_CAP; j++ {
+ tc.c.Unset(i, j)
+ }
+ }
+ testEmpty(tc.name, tc.c, tc.sets)
+ tc.c.Set(PERMITTED, CAP_CHOWN)
+ testPartial(tc.name, tc.c, PERMITTED)
+ tc.c.Clear(CAPS | BOUNDS)
+ testEmpty(tc.name, tc.c, tc.sets)
+ }
+}
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/enum.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/enum.go
new file mode 100644
index 00000000..e2900a4e
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/enum.go
@@ -0,0 +1,338 @@
+// 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
+)
+
+type Cap int
+
+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_psacct"
+ 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"
+ }
+ return "unknown"
+}
+
+const (
+ // POSIX-draft defined capabilities.
+
+ // 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
+
+ CAP_LAST_CAP = CAP_BLOCK_SUSPEND
+)
+
+const capUpperMask = (uint32(1) << (uint(CAP_LAST_CAP) - 31)) - 1
diff --git a/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/syscall_linux.go b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/syscall_linux.go
new file mode 100644
index 00000000..c18e6f69
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/syndtr/gocapability/capability/syscall_linux.go
@@ -0,0 +1,143 @@
+// 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 {
+ 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
+ data.data[0].permitted |= data.effective[0]
+ data.data[1].permitted |= data.effective[1]
+ }
+ 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
+}