Skip to content

Commit a579b44

Browse files
committed
Add a config file option
Allow multiple templates to be generated from one docker-gen process.
1 parent faf49cb commit a579b44

File tree

2 files changed

+97
-24
lines changed

2 files changed

+97
-24
lines changed

docker-gen.go

Lines changed: 86 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/json"
55
"flag"
66
"fmt"
7+
"github.com/BurntSushi/toml"
78
"github.com/fsouza/go-dockerclient"
89
"io"
910
"net"
@@ -23,6 +24,8 @@ var (
2324
watch bool
2425
notifyCmd string
2526
onlyExposed bool
27+
configFile string
28+
configs ConfigFile
2629
)
2730

2831
type Event struct {
@@ -42,6 +45,31 @@ type RuntimeContainer struct {
4245
Env map[string]string
4346
}
4447

48+
type Config struct {
49+
Template string
50+
Dest string
51+
Watch bool
52+
NotifyCmd string
53+
OnlyExposed bool
54+
}
55+
56+
type ConfigFile struct {
57+
Config []Config
58+
}
59+
60+
func (c *ConfigFile) filterWatches() ConfigFile {
61+
configWithWatches := []Config{}
62+
63+
for _, config := range c.Config {
64+
if config.Watch {
65+
configWithWatches = append(configWithWatches, config)
66+
}
67+
}
68+
return ConfigFile{
69+
Config: configWithWatches,
70+
}
71+
}
72+
4573
func deepGet(item interface{}, path string) interface{} {
4674
if path == "" {
4775
return item
@@ -90,10 +118,11 @@ func contains(a map[string]string, b string) bool {
90118
}
91119

92120
func usage() {
93-
println("Usage: docker-gen [-watch=false] [-notify=\"restart xyz\"] <template> [<dest>]")
121+
println("Usage: docker-gen [-config file] [-watch=false] [-notify=\"restart xyz\"] <template> [<dest>]")
94122
}
95123

96-
func generateFile(templatePath string, containers []*RuntimeContainer) {
124+
func generateFile(config Config, containers []*RuntimeContainer) {
125+
templatePath := config.Template
97126
tmpl, err := template.New(filepath.Base(templatePath)).Funcs(template.FuncMap{
98127
"contains": contains,
99128
"groupBy": groupBy,
@@ -102,12 +131,23 @@ func generateFile(templatePath string, containers []*RuntimeContainer) {
102131
panic(err)
103132
}
104133

134+
filteredContainers := []*RuntimeContainer{}
135+
if config.OnlyExposed {
136+
for _, container := range containers {
137+
if len(container.Addresses) > 0 {
138+
filteredContainers = append(filteredContainers, container)
139+
}
140+
}
141+
} else {
142+
filteredContainers = containers
143+
}
144+
105145
tmpl = tmpl
106146
dest := os.Stdout
107-
if flag.NArg() == 2 {
108-
dest, err = os.Create(flag.Arg(1))
147+
if config.Dest != "" {
148+
dest, err = os.Create(config.Dest)
109149
if err != nil {
110-
fmt.Println("unable to create dest file %s: %s\n", flag.Arg(1), err)
150+
fmt.Println("unable to create dest file %s: %s\n", config.Dest, err)
111151
os.Exit(1)
112152
}
113153
}
@@ -219,46 +259,67 @@ func generateFromContainers(client *docker.Client) {
219259
runtimeContainer.Env[parts[0]] = parts[1]
220260
}
221261

222-
if !onlyExposed {
223-
containers = append(containers, runtimeContainer)
224-
continue
225-
}
226-
227-
if onlyExposed && len(runtimeContainer.Addresses) > 0 {
228-
containers = append(containers, runtimeContainer)
229-
}
262+
containers = append(containers, runtimeContainer)
263+
}
230264

265+
for _, config := range configs.Config {
266+
generateFile(config, containers)
267+
runNotifyCmd(config)
231268
}
232269

233-
generateFile(flag.Arg(0), containers)
234270
}
235271

236-
func runNotifyCmd() {
237-
if notifyCmd == "" {
272+
func runNotifyCmd(config Config) {
273+
if config.NotifyCmd == "" {
238274
return
239275
}
240276

241-
args := strings.Split(notifyCmd, " ")
277+
args := strings.Split(config.NotifyCmd, " ")
242278
cmd := exec.Command(args[0], args[1:]...)
243-
output, err := cmd.CombinedOutput()
279+
_, err := cmd.CombinedOutput()
244280
if err != nil {
245-
fmt.Printf("error running notify command: %s\n", err)
281+
fmt.Printf("error running notify command: %s, %s\n", config.NotifyCmd, err)
246282
}
247-
print(string(output))
283+
}
248284

285+
func loadConfig(file string) error {
286+
_, err := toml.DecodeFile(file, &configs)
287+
if err != nil {
288+
return err
289+
}
290+
return nil
249291
}
250292

251293
func main() {
252294
flag.BoolVar(&watch, "watch", false, "watch for container changes")
253295
flag.BoolVar(&onlyExposed, "only-exposed", false, "only include containers with exposed ports")
254296
flag.StringVar(&notifyCmd, "notify", "", "run command after template is regenerated")
297+
flag.StringVar(&configFile, "config", "", "config file with template directives")
255298
flag.Parse()
256299

257-
if flag.NArg() < 1 {
300+
if flag.NArg() < 1 && configFile == "" {
258301
usage()
259302
os.Exit(1)
260303
}
261304

305+
if configFile != "" {
306+
err := loadConfig(configFile)
307+
if err != nil {
308+
fmt.Printf("error loading config %s: %s\n", configFile, err)
309+
os.Exit(1)
310+
}
311+
} else {
312+
config := Config{
313+
Template: flag.Arg(0),
314+
Dest: flag.Arg(1),
315+
Watch: watch,
316+
NotifyCmd: notifyCmd,
317+
OnlyExposed: onlyExposed,
318+
}
319+
configs = ConfigFile{
320+
Config: []Config{config}}
321+
}
322+
262323
endpoint := "unix:///var/run/docker.sock"
263324
client, err := docker.NewClient(endpoint)
264325

@@ -267,8 +328,10 @@ func main() {
267328
}
268329

269330
generateFromContainers(client)
270-
runNotifyCmd()
271-
if !watch {
331+
332+
configs = configs.filterWatches()
333+
334+
if len(configs.Config) == 0 {
272335
return
273336
}
274337

@@ -277,7 +340,6 @@ func main() {
277340
event := <-eventChan
278341
if event.Status == "start" || event.Status == "stop" || event.Status == "die" {
279342
generateFromContainers(client)
280-
runNotifyCmd()
281343
}
282344
}
283345

example.conf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[[config]]
2+
template = "templates/nginx.tmpl"
3+
dest = "/tmp/nginx.conf"
4+
onlyexposed = true
5+
notifycmd = "/etc/init.d/nginx reload"
6+
7+
[[config]]
8+
template = "templates/fluentd.conf.tmpl"
9+
dest = "/tmp/fluentd.conf"
10+
watch = true
11+
notifycmd = "echo test"

0 commit comments

Comments
 (0)