github.com/fcwu/docker@v1.4.2-0.20150115145920-2a69ca89f0df/daemon/list.go (about) 1 package daemon 2 3 import ( 4 "errors" 5 "fmt" 6 "strconv" 7 "strings" 8 9 "github.com/docker/docker/pkg/graphdb" 10 11 "github.com/docker/docker/engine" 12 "github.com/docker/docker/pkg/parsers/filters" 13 ) 14 15 // List returns an array of all containers registered in the daemon. 16 func (daemon *Daemon) List() []*Container { 17 return daemon.containers.List() 18 } 19 20 func (daemon *Daemon) Containers(job *engine.Job) engine.Status { 21 var ( 22 foundBefore bool 23 displayed int 24 all = job.GetenvBool("all") 25 since = job.Getenv("since") 26 before = job.Getenv("before") 27 n = job.GetenvInt("limit") 28 size = job.GetenvBool("size") 29 psFilters filters.Args 30 filt_exited []int 31 ) 32 outs := engine.NewTable("Created", 0) 33 34 psFilters, err := filters.FromParam(job.Getenv("filters")) 35 if err != nil { 36 return job.Error(err) 37 } 38 if i, ok := psFilters["exited"]; ok { 39 for _, value := range i { 40 code, err := strconv.Atoi(value) 41 if err != nil { 42 return job.Error(err) 43 } 44 filt_exited = append(filt_exited, code) 45 } 46 } 47 48 names := map[string][]string{} 49 daemon.ContainerGraph().Walk("/", func(p string, e *graphdb.Entity) error { 50 names[e.ID()] = append(names[e.ID()], p) 51 return nil 52 }, -1) 53 54 var beforeCont, sinceCont *Container 55 if before != "" { 56 beforeCont = daemon.Get(before) 57 if beforeCont == nil { 58 return job.Error(fmt.Errorf("Could not find container with name or id %s", before)) 59 } 60 } 61 62 if since != "" { 63 sinceCont = daemon.Get(since) 64 if sinceCont == nil { 65 return job.Error(fmt.Errorf("Could not find container with name or id %s", since)) 66 } 67 } 68 69 errLast := errors.New("last container") 70 writeCont := func(container *Container) error { 71 container.Lock() 72 defer container.Unlock() 73 if !container.Running && !all && n <= 0 && since == "" && before == "" { 74 return nil 75 } 76 77 if !psFilters.Match("name", container.Name) { 78 return nil 79 } 80 81 if !psFilters.Match("id", container.ID) { 82 return nil 83 } 84 85 if before != "" && !foundBefore { 86 if container.ID == beforeCont.ID { 87 foundBefore = true 88 } 89 return nil 90 } 91 if n > 0 && displayed == n { 92 return errLast 93 } 94 if since != "" { 95 if container.ID == sinceCont.ID { 96 return errLast 97 } 98 } 99 if len(filt_exited) > 0 && !container.Running { 100 should_skip := true 101 for _, code := range filt_exited { 102 if code == container.ExitCode { 103 should_skip = false 104 break 105 } 106 } 107 if should_skip { 108 return nil 109 } 110 } 111 112 if !psFilters.Match("status", container.State.StateString()) { 113 return nil 114 } 115 displayed++ 116 out := &engine.Env{} 117 out.SetJson("Id", container.ID) 118 out.SetList("Names", names[container.ID]) 119 out.SetJson("Image", daemon.Repositories().ImageName(container.ImageID)) 120 if len(container.Args) > 0 { 121 args := []string{} 122 for _, arg := range container.Args { 123 if strings.Contains(arg, " ") { 124 args = append(args, fmt.Sprintf("'%s'", arg)) 125 } else { 126 args = append(args, arg) 127 } 128 } 129 argsAsString := strings.Join(args, " ") 130 131 out.Set("Command", fmt.Sprintf("\"%s %s\"", container.Path, argsAsString)) 132 } else { 133 out.Set("Command", fmt.Sprintf("\"%s\"", container.Path)) 134 } 135 out.SetInt64("Created", container.Created.Unix()) 136 out.Set("Status", container.State.String()) 137 str, err := container.NetworkSettings.PortMappingAPI().ToListString() 138 if err != nil { 139 return err 140 } 141 out.Set("Ports", str) 142 if size { 143 sizeRw, sizeRootFs := container.GetSize() 144 out.SetInt64("SizeRw", sizeRw) 145 out.SetInt64("SizeRootFs", sizeRootFs) 146 } 147 outs.Add(out) 148 return nil 149 } 150 151 for _, container := range daemon.List() { 152 if err := writeCont(container); err != nil { 153 if err != errLast { 154 return job.Error(err) 155 } 156 break 157 } 158 } 159 outs.ReverseSort() 160 if _, err := outs.WriteListTo(job.Stdout); err != nil { 161 return job.Error(err) 162 } 163 return engine.StatusOK 164 }