docker.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. package docker
  2. import (
  3. "container/list"
  4. "fmt"
  5. "github.com/dotcloud/docker/fs"
  6. "io/ioutil"
  7. "log"
  8. "os"
  9. "path"
  10. "sort"
  11. )
  12. type Docker struct {
  13. root string
  14. repository string
  15. containers *list.List
  16. networkManager *NetworkManager
  17. Store *fs.Store
  18. }
  19. func (docker *Docker) List() []*Container {
  20. containers := new(History)
  21. for e := docker.containers.Front(); e != nil; e = e.Next() {
  22. containers.Add(e.Value.(*Container))
  23. }
  24. return *containers
  25. }
  26. func (docker *Docker) getContainerElement(id string) *list.Element {
  27. for e := docker.containers.Front(); e != nil; e = e.Next() {
  28. container := e.Value.(*Container)
  29. if container.Id == id {
  30. return e
  31. }
  32. }
  33. return nil
  34. }
  35. func (docker *Docker) Get(id string) *Container {
  36. e := docker.getContainerElement(id)
  37. if e == nil {
  38. return nil
  39. }
  40. return e.Value.(*Container)
  41. }
  42. func (docker *Docker) Exists(id string) bool {
  43. return docker.Get(id) != nil
  44. }
  45. func (docker *Docker) Create(id string, command string, args []string, image *fs.Image, config *Config) (*Container, error) {
  46. if docker.Exists(id) {
  47. return nil, fmt.Errorf("Container %v already exists", id)
  48. }
  49. root := path.Join(docker.repository, id)
  50. container, err := createContainer(id, root, command, args, image, config, docker.networkManager)
  51. if err != nil {
  52. return nil, err
  53. }
  54. docker.containers.PushBack(container)
  55. return container, nil
  56. }
  57. func (docker *Docker) Destroy(container *Container) error {
  58. element := docker.getContainerElement(container.Id)
  59. if element == nil {
  60. return fmt.Errorf("Container %v not found - maybe it was already destroyed?", container.Id)
  61. }
  62. if err := container.Stop(); err != nil {
  63. return err
  64. }
  65. if container.Mountpoint.Mounted() {
  66. if err := container.Mountpoint.Umount(); err != nil {
  67. log.Printf("Unable to umount container %v: %v", container.Id, err)
  68. }
  69. if err := container.Mountpoint.Deregister(); err != nil {
  70. log.Printf("Unable to deregiser mountpoint %v: %v", container.Mountpoint.Root, err)
  71. }
  72. }
  73. if err := os.RemoveAll(container.Root); err != nil {
  74. log.Printf("Unable to remove filesystem for %v: %v", container.Id, err)
  75. }
  76. docker.containers.Remove(element)
  77. return nil
  78. }
  79. func (docker *Docker) restore() error {
  80. dir, err := ioutil.ReadDir(docker.repository)
  81. if err != nil {
  82. return err
  83. }
  84. for _, v := range dir {
  85. container, err := loadContainer(docker.Store, path.Join(docker.repository, v.Name()), docker.networkManager)
  86. if err != nil {
  87. log.Printf("Failed to load container %v: %v", v.Name(), err)
  88. continue
  89. }
  90. docker.containers.PushBack(container)
  91. }
  92. return nil
  93. }
  94. func New() (*Docker, error) {
  95. return NewFromDirectory("/var/lib/docker")
  96. }
  97. func NewFromDirectory(root string) (*Docker, error) {
  98. docker_repo := path.Join(root, "containers")
  99. if err := os.MkdirAll(docker_repo, 0700); err != nil && !os.IsExist(err) {
  100. return nil, err
  101. }
  102. store, err := fs.New(path.Join(root, "images"))
  103. if err != nil {
  104. return nil, err
  105. }
  106. netManager, err := newNetworkManager(networkBridgeIface)
  107. if err != nil {
  108. return nil, err
  109. }
  110. docker := &Docker{
  111. root: root,
  112. repository: docker_repo,
  113. containers: list.New(),
  114. Store: store,
  115. networkManager: netManager,
  116. }
  117. if err := docker.restore(); err != nil {
  118. return nil, err
  119. }
  120. return docker, nil
  121. }
  122. type History []*Container
  123. func (history *History) Len() int {
  124. return len(*history)
  125. }
  126. func (history *History) Less(i, j int) bool {
  127. containers := *history
  128. return containers[j].When().Before(containers[i].When())
  129. }
  130. func (history *History) Swap(i, j int) {
  131. containers := *history
  132. tmp := containers[i]
  133. containers[i] = containers[j]
  134. containers[j] = tmp
  135. }
  136. func (history *History) Add(container *Container) {
  137. *history = append(*history, container)
  138. sort.Sort(history)
  139. }