Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for device passthrough #277

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ type RuntimeContainer struct {
ID string
Addresses []Address
Networks []Network
Devices []Device
Gateway string
Name string
Hostname string
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -451,4 +465,3 @@ $ make
### License

MIT

7 changes: 7 additions & 0 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -85,6 +91,7 @@ type RuntimeContainer struct {
ID string
Addresses []Address
Networks []Network
Devices []Device
Gateway string
Name string
Hostname string
Expand Down
9 changes: 9 additions & 0 deletions generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{},
Expand Down Expand Up @@ -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)
Expand Down
9 changes: 9 additions & 0 deletions generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
}

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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))
}
}

Expand Down
4 changes: 2 additions & 2 deletions utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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" {
Expand All @@ -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)
Expand Down