diff --git a/README.md b/README.md index d1e23cfb..22fed92b 100644 --- a/README.md +++ b/README.md @@ -209,6 +209,7 @@ type RuntimeContainer struct { ID string Addresses []Address Networks []Network + Devices []Device Gateway string Name string Hostname string @@ -277,6 +278,12 @@ type State struct { Running bool } +type Device struct { + PathOnHost string + PathInContainer string + Permissions string +} + // Accessible from the root in templates as .Docker type Docker struct { Name string @@ -308,7 +315,14 @@ For example, this is a JSON version of an emitted RuntimeContainer struct: "HostPort":"2222" } ], - "Gateway":"172.17.42.1", + "Devices":[ + { + "PathOnHost": "/dev/ttyACM0", + "PathInContainer": "/dev/ttyUSB0", + "Permissions": "rwm" + } + ], + "Gateway": "172.17.42.1", "Node": { "ID":"I2VY:P7PF:TZD5:PGWB:QTI7:QDSP:C5UD:DYKR:XKKK:TRG2:M2BL:DFUN", "Name":"docker-test", @@ -363,7 +377,7 @@ For example, this is a JSON version of an emitted RuntimeContainer struct: * *`json $value`*: Returns the JSON representation of `$value` as a `string`. * *`keys $map`*: Returns the keys from `$map`. If `$map` is `nil`, a `nil` is returned. If `$map` is not a `map`, an error will be thrown. * *`last $array`*: Returns the last value of an array. -* *`parseBool $string`*: parseBool returns the boolean value represented by the string. It accepts 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False. Any other value returns an error. Alias for [`strconv.ParseBool`](http://golang.org/pkg/strconv/#ParseBool) +* *`parseBool $string`*: parseBool returns the boolean value represented by the string. It accepts 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False. Any other value returns an error. Alias for [`strconv.ParseBool`](http://golang.org/pkg/strconv/#ParseBool) * *`replace $string $old $new $count`*: Replaces up to `$count` occurences of `$old` with `$new` in `$string`. Alias for [`strings.Replace`](http://golang.org/pkg/strings/#Replace) * *`sha1 $string`*: Returns the hexadecimal representation of the SHA1 hash of `$string`. * *`split $string $sep`*: Splits `$string` into a slice of substrings delimited by `$sep`. Alias for [`strings.Split`](http://golang.org/pkg/strings/#Split) @@ -451,4 +465,3 @@ $ make ### License MIT - diff --git a/context.go b/context.go index 80a6bd7d..7237137c 100644 --- a/context.go +++ b/context.go @@ -71,6 +71,12 @@ type Network struct { IPPrefixLen int } +type Device struct { + PathOnHost string + PathInContainer string + Permissions string +} + type Volume struct { Path string HostPath string @@ -85,6 +91,7 @@ type RuntimeContainer struct { ID string Addresses []Address Networks []Network + Devices []Device Gateway string Name string Hostname string diff --git a/generator.go b/generator.go index bf68be66..65d56207 100644 --- a/generator.go +++ b/generator.go @@ -381,6 +381,7 @@ func (g *generator) getContainers() ([]*RuntimeContainer, error) { Gateway: container.NetworkSettings.Gateway, Addresses: []Address{}, Networks: []Network{}, + Devices: []Device{}, Env: make(map[string]string), Volumes: make(map[string]Volume), Node: SwarmNode{}, @@ -447,6 +448,14 @@ func (g *generator) getContainers() ([]*RuntimeContainer, error) { }) } + for _, v := range container.HostConfig.Devices { + runtimeContainer.Devices = append(runtimeContainer.Devices, Device{ + PathOnHost: v.PathOnHost, + PathInContainer: v.PathInContainer, + Permissions: v.CgroupPermissions, + }) + } + runtimeContainer.Env = splitKeyValueSlice(container.Config.Env) runtimeContainer.Labels = container.Config.Labels containers = append(containers, runtimeContainer) diff --git a/generator_test.go b/generator_test.go index 87b8ce71..e2c56e74 100644 --- a/generator_test.go +++ b/generator_test.go @@ -95,6 +95,15 @@ func TestGenerateFromEvents(t *testing.T) { Ports: map[docker.Port][]docker.PortBinding{}, }, ResolvConfPath: "/etc/resolv.conf", + HostConfig: &docker.HostConfig{ + Devices: []docker.Device{ + docker.Device{ + PathOnHost: "/dev/ttyACM0", + PathInContainer: "/dev/ttyUSB0", + CgroupPermissions: "rwm", + }, + }, + }, } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) diff --git a/template_test.go b/template_test.go index dd1d58c3..71501ada 100644 --- a/template_test.go +++ b/template_test.go @@ -71,7 +71,7 @@ func TestKeysEmpty(t *testing.T) { } if len(input) != vk.Len() { - t.Fatalf("Incorrect key count; expected %s, got %s", len(input), vk.Len()) + t.Fatalf("Incorrect key count; expected %d, got %d", len(input), vk.Len()) } } @@ -269,11 +269,11 @@ func TestGroupByMulti(t *testing.T) { } if len(groups["demo1.localhost"]) != 2 { - t.Fatalf("expected 2 got %s", len(groups["demo1.localhost"])) + t.Fatalf("expected 2 got %d", len(groups["demo1.localhost"])) } if len(groups["demo2.localhost"]) != 1 { - t.Fatalf("expected 1 got %s", len(groups["demo2.localhost"])) + t.Fatalf("expected 1 got %d", len(groups["demo2.localhost"])) } if groups["demo2.localhost"][0].(RuntimeContainer).ID != "3" { t.Fatalf("expected 2 got %s", groups["demo2.localhost"][0].(RuntimeContainer).ID) @@ -785,7 +785,7 @@ func TestJson(t *testing.T) { t.Fatal(err) } if len(decoded) != len(containers) { - t.Fatal("Incorrect unmarshaled container count. Expected %d, got %d.", len(containers), len(decoded)) + t.Fatalf("Incorrect unmarshaled container count. Expected %d, got %d.", len(containers), len(decoded)) } } diff --git a/utils_test.go b/utils_test.go index 45186ac3..c5a8c17b 100644 --- a/utils_test.go +++ b/utils_test.go @@ -30,7 +30,7 @@ func TestDockerHostEndpoint(t *testing.T) { endpoint, err := GetEndpoint("") if err != nil { - t.Fatal("%s", err) + t.Fatalf("%s", err) } if endpoint != "tcp://127.0.0.1:4243" { @@ -48,7 +48,7 @@ func TestDockerFlagEndpoint(t *testing.T) { // flag value should override DOCKER_HOST and default value endpoint, err := GetEndpoint("tcp://127.0.0.1:5555") if err != nil { - t.Fatal("%s", err) + t.Fatalf("%s", err) } if endpoint != "tcp://127.0.0.1:5555" { t.Fatalf("Expected tcp://127.0.0.1:5555, got %s", endpoint)