docker.go 3.4 KB

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