Skip to content

Commit 2d77dc7

Browse files
committed
Add support for DOCKER_HOST env var
If DOCKER_HOST is set, docker-gen will use that as the address and default back to unix:///var/run/docker.sock if not specified.
1 parent 9b55a36 commit 2d77dc7

File tree

3 files changed

+127
-2
lines changed

3 files changed

+127
-2
lines changed

docker-gen.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ func generateFromEvents(client *docker.Client, configs ConfigFile) {
172172
eventChan := getEvents()
173173
for {
174174
event := <-eventChan
175+
if event == nil {
176+
return
177+
}
175178
if event.Status == "start" || event.Status == "stop" || event.Status == "die" {
176179
generateFromContainers(client)
177180
}
@@ -211,10 +214,13 @@ func main() {
211214
}
212215

213216
endpoint := "unix:///var/run/docker.sock"
217+
if os.Getenv("DOCKER_HOST") != "" {
218+
endpoint = os.Getenv("DOCKER_HOST")
219+
}
214220
client, err := docker.NewClient(endpoint)
215221

216222
if err != nil {
217-
panic(err)
223+
log.Fatalf("Unable to parse %s: %s", endpoint, err)
218224
}
219225

220226
generateFromContainers(client)

docker_client.go

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ package main
22

33
import (
44
"encoding/json"
5+
"fmt"
56
"io"
67
"log"
78
"net"
89
"net/http"
910
"net/http/httputil"
1011
"os"
1112
"os/signal"
13+
"strconv"
1214
"strings"
1315
"syscall"
1416

@@ -18,6 +20,68 @@ import (
1820
type DockerContainer struct {
1921
}
2022

23+
// based off of https://github.com/dotcloud/docker/blob/2a711d16e05b69328f2636f88f8eac035477f7e4/utils/utils.go
24+
func parseHost(addr string) (string, string, error) {
25+
26+
var (
27+
proto string
28+
host string
29+
port int
30+
)
31+
addr = strings.TrimSpace(addr)
32+
switch {
33+
case addr == "tcp://":
34+
return "", "", fmt.Errorf("Invalid bind address format: %s", addr)
35+
case strings.HasPrefix(addr, "unix://"):
36+
proto = "unix"
37+
addr = strings.TrimPrefix(addr, "unix://")
38+
if addr == "" {
39+
addr = "/var/run/docker.sock"
40+
}
41+
case strings.HasPrefix(addr, "tcp://"):
42+
proto = "tcp"
43+
addr = strings.TrimPrefix(addr, "tcp://")
44+
case strings.HasPrefix(addr, "fd://"):
45+
return "fd", addr, nil
46+
case addr == "":
47+
proto = "unix"
48+
addr = "/var/run/docker.sock"
49+
default:
50+
if strings.Contains(addr, "://") {
51+
return "", "", fmt.Errorf("Invalid bind address protocol: %s", addr)
52+
}
53+
proto = "tcp"
54+
}
55+
56+
if proto != "unix" && strings.Contains(addr, ":") {
57+
hostParts := strings.Split(addr, ":")
58+
if len(hostParts) != 2 {
59+
return "", "", fmt.Errorf("Invalid bind address format: %s", addr)
60+
}
61+
if hostParts[0] != "" {
62+
host = hostParts[0]
63+
} else {
64+
host = "127.0.0.1"
65+
}
66+
67+
if p, err := strconv.Atoi(hostParts[1]); err == nil && p != 0 {
68+
port = p
69+
} else {
70+
return "", "", fmt.Errorf("Invalid bind address format: %s", addr)
71+
}
72+
73+
} else if proto == "tcp" && !strings.Contains(addr, ":") {
74+
return "", "", fmt.Errorf("Invalid bind address format: %s", addr)
75+
} else {
76+
host = addr
77+
}
78+
if proto == "unix" {
79+
return proto, host, nil
80+
81+
}
82+
return proto, fmt.Sprintf("%s:%d", host, port), nil
83+
}
84+
2185
func splitDockerImage(img string) (string, string, string) {
2286
index := 0
2387
repository := img
@@ -39,7 +103,12 @@ func splitDockerImage(img string) (string, string, string) {
39103
}
40104

41105
func newConn() (*httputil.ClientConn, error) {
42-
conn, err := net.Dial("unix", "/var/run/docker.sock")
106+
proto, addr, err := parseHost(os.Getenv("DOCKER_HOST"))
107+
if err != nil {
108+
return nil, err
109+
}
110+
111+
conn, err := net.Dial(proto, addr)
43112
if err != nil {
44113
return nil, err
45114
}

docker_client_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,53 @@ func TestSplitDockerImageWithLocalRepositoryAndTag(t *testing.T) {
122122
}
123123

124124
}
125+
126+
func TestParseHostUnix(t *testing.T) {
127+
proto, addr, err := parseHost("unix:///var/run/docker.sock")
128+
if err != nil {
129+
t.Fatalf("%s", err)
130+
}
131+
if proto != "unix" || addr != "/var/run/docker.sock" {
132+
t.Fatal("failed to parse unix:///var/run/docker.sock")
133+
}
134+
}
135+
136+
func TestParseHostUnixDefault(t *testing.T) {
137+
proto, addr, err := parseHost("")
138+
if err != nil {
139+
t.Fatalf("%s", err)
140+
}
141+
if proto != "unix" || addr != "/var/run/docker.sock" {
142+
t.Fatal("failed to parse ''")
143+
}
144+
}
145+
146+
func TestParseHostUnixDefaultNoPath(t *testing.T) {
147+
proto, addr, err := parseHost("unix://")
148+
if err != nil {
149+
t.Fatalf("%s", err)
150+
}
151+
if proto != "unix" || addr != "/var/run/docker.sock" {
152+
t.Fatal("failed to parse unix://")
153+
}
154+
}
155+
156+
func TestParseHostTCP(t *testing.T) {
157+
proto, addr, err := parseHost("tcp://127.0.0.1:4243")
158+
if err != nil {
159+
t.Fatalf("%s", err)
160+
}
161+
if proto != "tcp" || addr != "127.0.0.1:4243" {
162+
t.Fatal("failed to parse tcp://127.0.0.1:4243")
163+
}
164+
}
165+
166+
func TestParseHostTCPDefault(t *testing.T) {
167+
proto, addr, err := parseHost("tcp://:4243")
168+
if err != nil {
169+
t.Fatalf("%s", err)
170+
}
171+
if proto != "tcp" || addr != "127.0.0.1:4243" {
172+
t.Fatal("failed to parse unix:///var/run/docker.sock")
173+
}
174+
}

0 commit comments

Comments
 (0)