docker.go 3.4 KB

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