docker.go 3.1 KB

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