summaryrefslogtreecommitdiff
path: root/contrib/host-integration/manager.go
blob: 6742ee4d7c0bfe47188249b748ce0f284b093f4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"github.com/dotcloud/docker"
	"os"
	"strings"
	"text/template"
)

var templates = map[string]string{

	"upstart": `description "{{.description}}"
author "{{.author}}"
start on filesystem and started lxc-net and started docker
stop on runlevel [!2345]
respawn
exec /home/vagrant/goroot/bin/docker start -a {{.container_id}}
`,

	"systemd": `[Unit]
	Description={{.description}}
	Author={{.author}}
	After=docker.service

[Service]
	Restart=always
	ExecStart=/usr/bin/docker start -a {{.container_id}}
	ExecStop=/usr/bin/docker stop -t 2 {{.container_id}}

[Install]
	WantedBy=local.target
`,
}

func main() {
	// Parse command line for custom options
	kind := flag.String("t", "upstart", "Type of manager requested")
	author := flag.String("a", "<none>", "Author of the image")
	description := flag.String("d", "<none>", "Description of the image")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "\nUsage: manager <container id>\n\n")
		flag.PrintDefaults()
	}
	flag.Parse()

	// We require at least the container ID
	if flag.NArg() != 1 {
		println(flag.NArg())
		flag.Usage()
		return
	}

	// Check that the requested process manager is supported
	if _, exists := templates[*kind]; !exists {
		panic("Unknown script template")
	}

	// Load the requested template
	tpl, err := template.New("processManager").Parse(templates[*kind])
	if err != nil {
		panic(err)
	}

	// Create stdout/stderr buffers
	bufOut := bytes.NewBuffer(nil)
	bufErr := bytes.NewBuffer(nil)

	// Instanciate the Docker CLI
	cli := docker.NewDockerCli(nil, bufOut, bufErr, "unix", "/var/run/docker.sock")
	// Retrieve the container info
	if err := cli.CmdInspect(flag.Arg(0)); err != nil {
		// As of docker v0.6.3, CmdInspect always returns nil
		panic(err)
	}

	// If there is nothing in the error buffer, then the Docker daemon is there and the container has been found
	if bufErr.Len() == 0 {
		// Unmarshall the resulting container data
		c := []*docker.Container{{}}
		if err := json.Unmarshal(bufOut.Bytes(), &c); err != nil {
			panic(err)
		}
		// Reset the buffers
		bufOut.Reset()
		bufErr.Reset()
		// Retrieve the info of the linked image
		if err := cli.CmdInspect(c[0].Image); err != nil {
			panic(err)
		}
		// If there is nothing in the error buffer, then the image has been found.
		if bufErr.Len() == 0 {
			// Unmarshall the resulting image data
			img := []*docker.Image{{}}
			if err := json.Unmarshal(bufOut.Bytes(), &img); err != nil {
				panic(err)
			}
			// If no author has been set, use the one from the image
			if *author == "<none>" && img[0].Author != "" {
				*author = strings.Replace(img[0].Author, "\"", "", -1)
			}
			// If no description has been set, use the comment from the image
			if *description == "<none>" && img[0].Comment != "" {
				*description = strings.Replace(img[0].Comment, "\"", "", -1)
			}
		}
	}

	/// Old version: Wrtie the resulting script to file
	// f, err := os.OpenFile(kind, os.O_CREATE|os.O_WRONLY, 0755)
	// if err != nil {
	// 	panic(err)
	// }
	// defer f.Close()

	// Create a map with needed data
	data := map[string]string{
		"author":       *author,
		"description":  *description,
		"container_id": flag.Arg(0),
	}

	// Process the template and output it on Stdout
	if err := tpl.Execute(os.Stdout, data); err != nil {
		panic(err)
	}
}