github.com/jandre/docker@v1.7.0/daemon/list.go (about) 1 package daemon 2 3 import ( 4 "errors" 5 "fmt" 6 "strconv" 7 "strings" 8 9 "github.com/docker/docker/api/types" 10 "github.com/docker/docker/nat" 11 "github.com/docker/docker/pkg/graphdb" 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 type ContainersConfig struct { 21 All bool 22 Since string 23 Before string 24 Limit int 25 Size bool 26 Filters string 27 } 28 29 func (daemon *Daemon) Containers(config *ContainersConfig) ([]*types.Container, error) { 30 var ( 31 foundBefore bool 32 displayed int 33 all = config.All 34 n = config.Limit 35 psFilters filters.Args 36 filtExited []int 37 ) 38 containers := []*types.Container{} 39 40 psFilters, err := filters.FromParam(config.Filters) 41 if err != nil { 42 return nil, err 43 } 44 if i, ok := psFilters["exited"]; ok { 45 for _, value := range i { 46 code, err := strconv.Atoi(value) 47 if err != nil { 48 return nil, err 49 } 50 filtExited = append(filtExited, code) 51 } 52 } 53 54 if i, ok := psFilters["status"]; ok { 55 for _, value := range i { 56 if value == "exited" { 57 all = true 58 } 59 } 60 } 61 names := map[string][]string{} 62 daemon.ContainerGraph().Walk("/", func(p string, e *graphdb.Entity) error { 63 names[e.ID()] = append(names[e.ID()], p) 64 return nil 65 }, 1) 66 67 var beforeCont, sinceCont *Container 68 if config.Before != "" { 69 beforeCont, err = daemon.Get(config.Before) 70 if err != nil { 71 return nil, err 72 } 73 } 74 75 if config.Since != "" { 76 sinceCont, err = daemon.Get(config.Since) 77 if err != nil { 78 return nil, err 79 } 80 } 81 82 errLast := errors.New("last container") 83 writeCont := func(container *Container) error { 84 container.Lock() 85 defer container.Unlock() 86 if !container.Running && !all && n <= 0 && config.Since == "" && config.Before == "" { 87 return nil 88 } 89 if !psFilters.Match("name", container.Name) { 90 return nil 91 } 92 93 if !psFilters.Match("id", container.ID) { 94 return nil 95 } 96 97 if !psFilters.MatchKVList("label", container.Config.Labels) { 98 return nil 99 } 100 101 if config.Before != "" && !foundBefore { 102 if container.ID == beforeCont.ID { 103 foundBefore = true 104 } 105 return nil 106 } 107 if n > 0 && displayed == n { 108 return errLast 109 } 110 if config.Since != "" { 111 if container.ID == sinceCont.ID { 112 return errLast 113 } 114 } 115 if len(filtExited) > 0 { 116 shouldSkip := true 117 for _, code := range filtExited { 118 if code == container.ExitCode && !container.Running { 119 shouldSkip = false 120 break 121 } 122 } 123 if shouldSkip { 124 return nil 125 } 126 } 127 128 if !psFilters.Match("status", container.State.StateString()) { 129 return nil 130 } 131 displayed++ 132 newC := &types.Container{ 133 ID: container.ID, 134 Names: names[container.ID], 135 } 136 newC.Image = container.Config.Image 137 if len(container.Args) > 0 { 138 args := []string{} 139 for _, arg := range container.Args { 140 if strings.Contains(arg, " ") { 141 args = append(args, fmt.Sprintf("'%s'", arg)) 142 } else { 143 args = append(args, arg) 144 } 145 } 146 argsAsString := strings.Join(args, " ") 147 148 newC.Command = fmt.Sprintf("%s %s", container.Path, argsAsString) 149 } else { 150 newC.Command = fmt.Sprintf("%s", container.Path) 151 } 152 newC.Created = int(container.Created.Unix()) 153 newC.Status = container.State.String() 154 155 newC.Ports = []types.Port{} 156 for port, bindings := range container.NetworkSettings.Ports { 157 p, _ := nat.ParsePort(port.Port()) 158 if len(bindings) == 0 { 159 newC.Ports = append(newC.Ports, types.Port{ 160 PrivatePort: p, 161 Type: port.Proto(), 162 }) 163 continue 164 } 165 for _, binding := range bindings { 166 h, _ := nat.ParsePort(binding.HostPort) 167 newC.Ports = append(newC.Ports, types.Port{ 168 PrivatePort: p, 169 PublicPort: h, 170 Type: port.Proto(), 171 IP: binding.HostIp, 172 }) 173 } 174 } 175 176 if config.Size { 177 sizeRw, sizeRootFs := container.GetSize() 178 newC.SizeRw = int(sizeRw) 179 newC.SizeRootFs = int(sizeRootFs) 180 } 181 newC.Labels = container.Config.Labels 182 containers = append(containers, newC) 183 return nil 184 } 185 186 for _, container := range daemon.List() { 187 if err := writeCont(container); err != nil { 188 if err != errLast { 189 return nil, err 190 } 191 break 192 } 193 } 194 return containers, nil 195 }