manager.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package main
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "flag"
  6. "fmt"
  7. "github.com/docker/docker"
  8. "os"
  9. "strings"
  10. "text/template"
  11. )
  12. var templates = map[string]string{
  13. "upstart": `description "{{.description}}"
  14. author "{{.author}}"
  15. start on filesystem and started lxc-net and started docker
  16. stop on runlevel [!2345]
  17. respawn
  18. exec /home/vagrant/goroot/bin/docker start -a {{.container_id}}
  19. `,
  20. "systemd": `[Unit]
  21. Description={{.description}}
  22. Author={{.author}}
  23. After=docker.service
  24. [Service]
  25. Restart=always
  26. ExecStart=/usr/bin/docker start -a {{.container_id}}
  27. ExecStop=/usr/bin/docker stop -t 2 {{.container_id}}
  28. [Install]
  29. WantedBy=local.target
  30. `,
  31. }
  32. func main() {
  33. // Parse command line for custom options
  34. kind := flag.String("t", "upstart", "Type of manager requested")
  35. author := flag.String("a", "<none>", "Author of the image")
  36. description := flag.String("d", "<none>", "Description of the image")
  37. flag.Usage = func() {
  38. fmt.Fprintf(os.Stderr, "\nUsage: manager <container id>\n\n")
  39. flag.PrintDefaults()
  40. }
  41. flag.Parse()
  42. // We require at least the container ID
  43. if flag.NArg() != 1 {
  44. println(flag.NArg())
  45. flag.Usage()
  46. return
  47. }
  48. // Check that the requested process manager is supported
  49. if _, exists := templates[*kind]; !exists {
  50. panic("Unknown script template")
  51. }
  52. // Load the requested template
  53. tpl, err := template.New("processManager").Parse(templates[*kind])
  54. if err != nil {
  55. panic(err)
  56. }
  57. // Create stdout/stderr buffers
  58. bufOut := bytes.NewBuffer(nil)
  59. bufErr := bytes.NewBuffer(nil)
  60. // Instanciate the Docker CLI
  61. cli := docker.NewDockerCli(nil, bufOut, bufErr, "unix", "/var/run/docker.sock", false, nil)
  62. // Retrieve the container info
  63. if err := cli.CmdInspect(flag.Arg(0)); err != nil {
  64. // As of docker v0.6.3, CmdInspect always returns nil
  65. panic(err)
  66. }
  67. // If there is nothing in the error buffer, then the Docker daemon is there and the container has been found
  68. if bufErr.Len() == 0 {
  69. // Unmarshall the resulting container data
  70. c := []*docker.Container{{}}
  71. if err := json.Unmarshal(bufOut.Bytes(), &c); err != nil {
  72. panic(err)
  73. }
  74. // Reset the buffers
  75. bufOut.Reset()
  76. bufErr.Reset()
  77. // Retrieve the info of the linked image
  78. if err := cli.CmdInspect(c[0].Image); err != nil {
  79. panic(err)
  80. }
  81. // If there is nothing in the error buffer, then the image has been found.
  82. if bufErr.Len() == 0 {
  83. // Unmarshall the resulting image data
  84. img := []*docker.Image{{}}
  85. if err := json.Unmarshal(bufOut.Bytes(), &img); err != nil {
  86. panic(err)
  87. }
  88. // If no author has been set, use the one from the image
  89. if *author == "<none>" && img[0].Author != "" {
  90. *author = strings.Replace(img[0].Author, "\"", "", -1)
  91. }
  92. // If no description has been set, use the comment from the image
  93. if *description == "<none>" && img[0].Comment != "" {
  94. *description = strings.Replace(img[0].Comment, "\"", "", -1)
  95. }
  96. }
  97. }
  98. /// Old version: Wrtie the resulting script to file
  99. // f, err := os.OpenFile(kind, os.O_CREATE|os.O_WRONLY, 0755)
  100. // if err != nil {
  101. // panic(err)
  102. // }
  103. // defer f.Close()
  104. // Create a map with needed data
  105. data := map[string]string{
  106. "author": *author,
  107. "description": *description,
  108. "container_id": flag.Arg(0),
  109. }
  110. // Process the template and output it on Stdout
  111. if err := tpl.Execute(os.Stdout, data); err != nil {
  112. panic(err)
  113. }
  114. }