moby--moby/docker.go

162 lines
3.7 KiB
Go
Raw Normal View History

2013-01-19 00:13:39 +00:00
package docker
import (
"container/list"
"fmt"
"github.com/dotcloud/docker/fs"
2013-01-19 00:13:39 +00:00
"io/ioutil"
"log"
2013-01-19 00:13:39 +00:00
"os"
"path"
"sort"
2013-01-19 00:13:39 +00:00
)
type Docker struct {
2013-02-28 19:52:07 +00:00
root string
repository string
containers *list.List
networkManager *NetworkManager
2013-03-11 12:42:36 +00:00
Store *fs.Store
2013-01-19 00:13:39 +00:00
}
func (docker *Docker) List() []*Container {
containers := new(History)
2013-01-19 00:13:39 +00:00
for e := docker.containers.Front(); e != nil; e = e.Next() {
containers.Add(e.Value.(*Container))
}
return *containers
2013-01-19 00:13:39 +00:00
}
2013-01-22 02:39:52 +00:00
func (docker *Docker) getContainerElement(id string) *list.Element {
2013-01-19 00:13:39 +00:00
for e := docker.containers.Front(); e != nil; e = e.Next() {
container := e.Value.(*Container)
2013-01-22 02:39:52 +00:00
if container.Id == id {
2013-01-19 00:13:39 +00:00
return e
}
}
return nil
}
2013-01-22 02:39:52 +00:00
func (docker *Docker) Get(id string) *Container {
e := docker.getContainerElement(id)
2013-01-19 00:13:39 +00:00
if e == nil {
return nil
}
return e.Value.(*Container)
}
2013-01-22 02:39:52 +00:00
func (docker *Docker) Exists(id string) bool {
return docker.Get(id) != nil
2013-01-19 00:13:39 +00:00
}
func (docker *Docker) Create(id string, command string, args []string, image *fs.Image, config *Config) (*Container, error) {
2013-01-22 02:39:52 +00:00
if docker.Exists(id) {
return nil, fmt.Errorf("Container %v already exists", id)
2013-01-19 00:13:39 +00:00
}
2013-01-22 02:39:52 +00:00
root := path.Join(docker.repository, id)
2013-03-11 12:42:36 +00:00
container, err := createContainer(id, root, command, args, image, config, docker.networkManager)
2013-01-19 00:13:39 +00:00
if err != nil {
return nil, err
}
docker.containers.PushBack(container)
return container, nil
}
func (docker *Docker) Destroy(container *Container) error {
2013-01-22 02:39:52 +00:00
element := docker.getContainerElement(container.Id)
2013-01-19 00:13:39 +00:00
if element == nil {
2013-01-22 02:39:52 +00:00
return fmt.Errorf("Container %v not found - maybe it was already destroyed?", container.Id)
2013-01-19 00:13:39 +00:00
}
if err := container.Stop(); err != nil {
return err
}
if container.Mountpoint.Mounted() {
if err := container.Mountpoint.Umount(); err != nil {
log.Printf("Unable to umount container %v: %v", container.Id, err)
}
}
if err := container.Mountpoint.Deregister(); err != nil {
log.Printf("Unable to deregiser mountpoint %v: %v", container.Mountpoint.Root, err)
}
2013-01-19 00:13:39 +00:00
if err := os.RemoveAll(container.Root); err != nil {
log.Printf("Unable to remove filesystem for %v: %v", container.Id, err)
2013-01-19 00:13:39 +00:00
}
docker.containers.Remove(element)
return nil
}
func (docker *Docker) restore() error {
dir, err := ioutil.ReadDir(docker.repository)
if err != nil {
return err
}
for _, v := range dir {
2013-03-11 12:50:09 +00:00
container, err := loadContainer(docker.Store, path.Join(docker.repository, v.Name()), docker.networkManager)
2013-01-19 00:13:39 +00:00
if err != nil {
log.Printf("Failed to load container %v: %v", v.Name(), err)
2013-01-19 00:13:39 +00:00
continue
}
docker.containers.PushBack(container)
}
return nil
}
func New() (*Docker, error) {
return NewFromDirectory("/var/lib/docker")
}
func NewFromDirectory(root string) (*Docker, error) {
docker_repo := path.Join(root, "containers")
if err := os.MkdirAll(docker_repo, 0700); err != nil && !os.IsExist(err) {
return nil, err
}
store, err := fs.New(path.Join(root, "images"))
if err != nil {
return nil, err
}
2013-02-28 19:52:07 +00:00
netManager, err := newNetworkManager(networkBridgeIface)
if err != nil {
return nil, err
}
2013-01-19 00:13:39 +00:00
docker := &Docker{
2013-02-28 19:52:07 +00:00
root: root,
repository: docker_repo,
2013-02-28 19:52:07 +00:00
containers: list.New(),
2013-03-11 12:42:36 +00:00
Store: store,
2013-02-28 19:52:07 +00:00
networkManager: netManager,
2013-01-19 00:13:39 +00:00
}
if err := docker.restore(); err != nil {
return nil, err
}
return docker, nil
}
type History []*Container
func (history *History) Len() int {
return len(*history)
}
func (history *History) Less(i, j int) bool {
containers := *history
return containers[j].When().Before(containers[i].When())
}
func (history *History) Swap(i, j int) {
containers := *history
tmp := containers[i]
containers[i] = containers[j]
containers[j] = tmp
}
func (history *History) Add(container *Container) {
*history = append(*history, container)
sort.Sort(history)
}