github.com/gunjan5/docker@v1.8.2/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/pkg/graphdb" 11 "github.com/docker/docker/pkg/nat" 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 !isValidStateString(value) { 57 return nil, errors.New("Unrecognised filter value for status") 58 } 59 if value == "exited" || value == "created" { 60 all = true 61 } 62 } 63 } 64 names := map[string][]string{} 65 daemon.ContainerGraph().Walk("/", func(p string, e *graphdb.Entity) error { 66 names[e.ID()] = append(names[e.ID()], p) 67 return nil 68 }, 1) 69 70 var beforeCont, sinceCont *Container 71 if config.Before != "" { 72 beforeCont, err = daemon.Get(config.Before) 73 if err != nil { 74 return nil, err 75 } 76 } 77 78 if config.Since != "" { 79 sinceCont, err = daemon.Get(config.Since) 80 if err != nil { 81 return nil, err 82 } 83 } 84 85 errLast := errors.New("last container") 86 writeCont := func(container *Container) error { 87 container.Lock() 88 defer container.Unlock() 89 if !container.Running && !all && n <= 0 && config.Since == "" && config.Before == "" { 90 return nil 91 } 92 if !psFilters.Match("name", container.Name) { 93 return nil 94 } 95 96 if !psFilters.Match("id", container.ID) { 97 return nil 98 } 99 100 if !psFilters.MatchKVList("label", container.Config.Labels) { 101 return nil 102 } 103 104 if config.Before != "" && !foundBefore { 105 if container.ID == beforeCont.ID { 106 foundBefore = true 107 } 108 return nil 109 } 110 if n > 0 && displayed == n { 111 return errLast 112 } 113 if config.Since != "" { 114 if container.ID == sinceCont.ID { 115 return errLast 116 } 117 } 118 if len(filtExited) > 0 { 119 shouldSkip := true 120 for _, code := range filtExited { 121 if code == container.ExitCode && !container.Running { 122 shouldSkip = false 123 break 124 } 125 } 126 if shouldSkip { 127 return nil 128 } 129 } 130 131 if !psFilters.Match("status", container.State.StateString()) { 132 return nil 133 } 134 displayed++ 135 newC := &types.Container{ 136 ID: container.ID, 137 Names: names[container.ID], 138 } 139 newC.Image = container.Config.Image 140 if len(container.Args) > 0 { 141 args := []string{} 142 for _, arg := range container.Args { 143 if strings.Contains(arg, " ") { 144 args = append(args, fmt.Sprintf("'%s'", arg)) 145 } else { 146 args = append(args, arg) 147 } 148 } 149 argsAsString := strings.Join(args, " ") 150 151 newC.Command = fmt.Sprintf("%s %s", container.Path, argsAsString) 152 } else { 153 newC.Command = fmt.Sprintf("%s", container.Path) 154 } 155 newC.Created = int(container.Created.Unix()) 156 newC.Status = container.State.String() 157 newC.HostConfig.NetworkMode = string(container.HostConfig().NetworkMode) 158 159 newC.Ports = []types.Port{} 160 for port, bindings := range container.NetworkSettings.Ports { 161 p, err := nat.ParsePort(port.Port()) 162 if err != nil { 163 return err 164 } 165 if len(bindings) == 0 { 166 newC.Ports = append(newC.Ports, types.Port{ 167 PrivatePort: p, 168 Type: port.Proto(), 169 }) 170 continue 171 } 172 for _, binding := range bindings { 173 h, err := nat.ParsePort(binding.HostPort) 174 if err != nil { 175 return err 176 } 177 newC.Ports = append(newC.Ports, types.Port{ 178 PrivatePort: p, 179 PublicPort: h, 180 Type: port.Proto(), 181 IP: binding.HostIP, 182 }) 183 } 184 } 185 186 if config.Size { 187 sizeRw, sizeRootFs := container.GetSize() 188 newC.SizeRw = int(sizeRw) 189 newC.SizeRootFs = int(sizeRootFs) 190 } 191 newC.Labels = container.Config.Labels 192 containers = append(containers, newC) 193 return nil 194 } 195 196 for _, container := range daemon.List() { 197 if err := writeCont(container); err != nil { 198 if err != errLast { 199 return nil, err 200 } 201 break 202 } 203 } 204 return containers, nil 205 }