docker.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. package docker
  2. import (
  3. "errors"
  4. "strings"
  5. "bitbucket.org/robert2206/automation/modules/settings"
  6. docker "github.com/fsouza/go-dockerclient"
  7. )
  8. var (
  9. // errorContainerRemove is a dispatched error when container cannot be removed
  10. errorContainerRemove = errors.New("container cannot be removed")
  11. )
  12. // Image represent a docker image
  13. type Image struct {
  14. ID string
  15. Tag string
  16. Size int64
  17. }
  18. // Network represent a network ip used by docker
  19. type Network struct {
  20. ID string
  21. IP string
  22. }
  23. // Port represent a port user by docker container
  24. type Port struct {
  25. IP string
  26. Type string
  27. PublicPort int64
  28. PrivatePort int64
  29. }
  30. // Container represent docker container
  31. type Container struct {
  32. ID string
  33. Name string
  34. Image string
  35. State string
  36. Ports []*Port
  37. Networks map[string]*Network
  38. }
  39. // Create a container
  40. func Create(name string, image string) (*Container, error) {
  41. cli, err := getDockerClient()
  42. if err != nil {
  43. return nil, err
  44. }
  45. ctr, err := cli.CreateContainer(docker.CreateContainerOptions{
  46. Name: name,
  47. Config: &docker.Config{
  48. Image: image,
  49. Memory: 102400,
  50. MemorySwap: 102400,
  51. },
  52. })
  53. if err != nil {
  54. return nil, err
  55. }
  56. return &Container{
  57. ID: ctr.ID,
  58. Name: ctr.Name,
  59. Image: ctr.Image,
  60. State: ctr.State.Status,
  61. }, nil
  62. }
  63. // Remove a container
  64. func Remove(idOrName string) error {
  65. cli, err := getDockerClient()
  66. if err != nil {
  67. return err
  68. }
  69. ctr := GetContainer(idOrName)
  70. if ctr == nil {
  71. return errorContainerRemove
  72. }
  73. return cli.RemoveContainer(docker.RemoveContainerOptions{
  74. ID: ctr.ID,
  75. RemoveVolumes: true,
  76. })
  77. }
  78. // Start container
  79. func Start(idOrName string) error {
  80. cli, err := getClientFor(idOrName)
  81. if err != nil {
  82. return err
  83. }
  84. return cli.StartContainer(idOrName, nil)
  85. }
  86. // Restart container
  87. func Restart(idOrName string) error {
  88. cli, err := getClientFor(idOrName)
  89. if err != nil {
  90. return err
  91. }
  92. return cli.RestartContainer(idOrName, 3)
  93. }
  94. // Stop container
  95. func Stop(idOrName string) error {
  96. cli, err := getClientFor(idOrName)
  97. if err != nil {
  98. return err
  99. }
  100. return cli.StopContainer(idOrName, 3)
  101. }
  102. // GetAllImages returns all docker images
  103. func GetAllImages() ([]*Image, error) {
  104. cli, err := getDockerClient()
  105. if err != nil {
  106. return nil, err
  107. }
  108. imgs, err := cli.ListImages(docker.ListImagesOptions{
  109. All: true,
  110. })
  111. if err != nil {
  112. return nil, err
  113. }
  114. results := make([]*Image, len(imgs))
  115. for i, img := range imgs {
  116. results[i] = &Image{
  117. ID: img.ID,
  118. Tag: img.RepoTags[0],
  119. Size: img.Size,
  120. }
  121. }
  122. return results, nil
  123. }
  124. // GetAllContainers returns all docker containers
  125. func GetAllContainers() ([]*Container, error) {
  126. cli, err := getDockerClient()
  127. if err != nil {
  128. return nil, err
  129. }
  130. ctrs, err := cli.ListContainers(docker.ListContainersOptions{
  131. All: true,
  132. })
  133. if err != nil {
  134. return nil, err
  135. }
  136. results := make([]*Container, len(ctrs))
  137. for i, ctr := range ctrs {
  138. results[i] = &Container{
  139. ID: ctr.ID,
  140. Name: ctr.Names[0],
  141. Image: ctr.Image,
  142. State: ctr.State,
  143. Ports: func() []*Port {
  144. prts := make([]*Port, len(ctr.Ports))
  145. for j, prt := range ctr.Ports {
  146. prts[j] = &Port{
  147. IP: prt.IP,
  148. Type: prt.Type,
  149. PublicPort: prt.PublicPort,
  150. PrivatePort: prt.PrivatePort,
  151. }
  152. }
  153. return prts
  154. }(),
  155. Networks: func() map[string]*Network {
  156. netws := make(map[string]*Network, len(ctr.Networks.Networks))
  157. for k, netw := range ctr.Networks.Networks {
  158. netws[k] = &Network{
  159. ID: netw.NetworkID,
  160. IP: netw.IPAddress,
  161. }
  162. }
  163. return netws
  164. }(),
  165. }
  166. }
  167. return results, nil
  168. }
  169. // GetContainer return container matched by id or name
  170. func GetContainer(idOrName string) *Container {
  171. ctrs, err := GetAllContainers()
  172. if err != nil {
  173. return nil
  174. }
  175. return func() *Container {
  176. for _, ctr := range ctrs {
  177. if ctr.ID == idOrName || ctr.Name == idOrName {
  178. return ctr
  179. }
  180. }
  181. return nil
  182. }()
  183. }
  184. // GetAllPublicPorts get all public exposed ports
  185. func GetAllPublicPorts() ([]int64, error) {
  186. ctrs, err := GetAllContainers()
  187. if err != nil {
  188. return nil, err
  189. }
  190. return func() []int64 {
  191. var prts []int64
  192. for _, ctr := range ctrs {
  193. for _, ptr := range ctr.Ports {
  194. prts = append(prts, ptr.PublicPort)
  195. }
  196. }
  197. return prts
  198. }(), nil
  199. }
  200. // GetNetwork get network used by container
  201. func GetNetwork(idOrName string) {
  202. }
  203. // GetPrivateIP get private ip used by container
  204. func GetPrivateIP(idOrName string) {
  205. }
  206. func getClientFor(idOrName string) (*docker.Client, error) {
  207. err := checkIdOrName(idOrName)
  208. if err != nil {
  209. return nil, err
  210. }
  211. cli, err := getDockerClient()
  212. if err != nil {
  213. return nil, err
  214. }
  215. return cli, nil
  216. }
  217. func checkIdOrName(idOrName string) error {
  218. if len(strings.TrimSpace(idOrName)) == 0 {
  219. return errors.New("container id or name not provided")
  220. }
  221. return nil
  222. }
  223. func getDockerClient() (*docker.Client, error) {
  224. endpoint := settings.Ctx.DockerSockDir
  225. if strings.HasSuffix(endpoint, ".sock") {
  226. endpoint = strings.Join([]string{"unix:", endpoint}, "/")
  227. }
  228. return docker.NewClient(endpoint)
  229. }