docker.go 5.3 KB

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