mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
645c020f5a
This patch include the following fixs: - fix image name error when docker ps - fix docker events test failure: use the exact image name for filter - fix docker build CI test failure due to "docker events" change Because of change of daemon log behavior. Now we record the exact Image name as you typed. So docker run -d busybux sh and docker run -d busybox:latest are not the same in the log. So it will affect the docker events. So change the related CI Signed-off-by: Liu Hua <sdu.liu@huawei.com>
195 lines
4.2 KiB
Go
195 lines
4.2 KiB
Go
package daemon
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/docker/docker/api/types"
|
|
"github.com/docker/docker/nat"
|
|
"github.com/docker/docker/pkg/graphdb"
|
|
"github.com/docker/docker/pkg/parsers/filters"
|
|
)
|
|
|
|
// List returns an array of all containers registered in the daemon.
|
|
func (daemon *Daemon) List() []*Container {
|
|
return daemon.containers.List()
|
|
}
|
|
|
|
type ContainersConfig struct {
|
|
All bool
|
|
Since string
|
|
Before string
|
|
Limit int
|
|
Size bool
|
|
Filters string
|
|
}
|
|
|
|
func (daemon *Daemon) Containers(config *ContainersConfig) ([]*types.Container, error) {
|
|
var (
|
|
foundBefore bool
|
|
displayed int
|
|
all = config.All
|
|
n = config.Limit
|
|
psFilters filters.Args
|
|
filtExited []int
|
|
)
|
|
containers := []*types.Container{}
|
|
|
|
psFilters, err := filters.FromParam(config.Filters)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if i, ok := psFilters["exited"]; ok {
|
|
for _, value := range i {
|
|
code, err := strconv.Atoi(value)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
filtExited = append(filtExited, code)
|
|
}
|
|
}
|
|
|
|
if i, ok := psFilters["status"]; ok {
|
|
for _, value := range i {
|
|
if value == "exited" {
|
|
all = true
|
|
}
|
|
}
|
|
}
|
|
names := map[string][]string{}
|
|
daemon.ContainerGraph().Walk("/", func(p string, e *graphdb.Entity) error {
|
|
names[e.ID()] = append(names[e.ID()], p)
|
|
return nil
|
|
}, 1)
|
|
|
|
var beforeCont, sinceCont *Container
|
|
if config.Before != "" {
|
|
beforeCont, err = daemon.Get(config.Before)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if config.Since != "" {
|
|
sinceCont, err = daemon.Get(config.Since)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
errLast := errors.New("last container")
|
|
writeCont := func(container *Container) error {
|
|
container.Lock()
|
|
defer container.Unlock()
|
|
if !container.Running && !all && n <= 0 && config.Since == "" && config.Before == "" {
|
|
return nil
|
|
}
|
|
if !psFilters.Match("name", container.Name) {
|
|
return nil
|
|
}
|
|
|
|
if !psFilters.Match("id", container.ID) {
|
|
return nil
|
|
}
|
|
|
|
if !psFilters.MatchKVList("label", container.Config.Labels) {
|
|
return nil
|
|
}
|
|
|
|
if config.Before != "" && !foundBefore {
|
|
if container.ID == beforeCont.ID {
|
|
foundBefore = true
|
|
}
|
|
return nil
|
|
}
|
|
if n > 0 && displayed == n {
|
|
return errLast
|
|
}
|
|
if config.Since != "" {
|
|
if container.ID == sinceCont.ID {
|
|
return errLast
|
|
}
|
|
}
|
|
if len(filtExited) > 0 {
|
|
shouldSkip := true
|
|
for _, code := range filtExited {
|
|
if code == container.ExitCode && !container.Running {
|
|
shouldSkip = false
|
|
break
|
|
}
|
|
}
|
|
if shouldSkip {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
if !psFilters.Match("status", container.State.StateString()) {
|
|
return nil
|
|
}
|
|
displayed++
|
|
newC := &types.Container{
|
|
ID: container.ID,
|
|
Names: names[container.ID],
|
|
}
|
|
newC.Image = container.Config.Image
|
|
if len(container.Args) > 0 {
|
|
args := []string{}
|
|
for _, arg := range container.Args {
|
|
if strings.Contains(arg, " ") {
|
|
args = append(args, fmt.Sprintf("'%s'", arg))
|
|
} else {
|
|
args = append(args, arg)
|
|
}
|
|
}
|
|
argsAsString := strings.Join(args, " ")
|
|
|
|
newC.Command = fmt.Sprintf("%s %s", container.Path, argsAsString)
|
|
} else {
|
|
newC.Command = fmt.Sprintf("%s", container.Path)
|
|
}
|
|
newC.Created = int(container.Created.Unix())
|
|
newC.Status = container.State.String()
|
|
|
|
newC.Ports = []types.Port{}
|
|
for port, bindings := range container.NetworkSettings.Ports {
|
|
p, _ := nat.ParsePort(port.Port())
|
|
if len(bindings) == 0 {
|
|
newC.Ports = append(newC.Ports, types.Port{
|
|
PrivatePort: p,
|
|
Type: port.Proto(),
|
|
})
|
|
continue
|
|
}
|
|
for _, binding := range bindings {
|
|
h, _ := nat.ParsePort(binding.HostPort)
|
|
newC.Ports = append(newC.Ports, types.Port{
|
|
PrivatePort: p,
|
|
PublicPort: h,
|
|
Type: port.Proto(),
|
|
IP: binding.HostIp,
|
|
})
|
|
}
|
|
}
|
|
|
|
if config.Size {
|
|
sizeRw, sizeRootFs := container.GetSize()
|
|
newC.SizeRw = int(sizeRw)
|
|
newC.SizeRootFs = int(sizeRootFs)
|
|
}
|
|
newC.Labels = container.Config.Labels
|
|
containers = append(containers, newC)
|
|
return nil
|
|
}
|
|
|
|
for _, container := range daemon.List() {
|
|
if err := writeCont(container); err != nil {
|
|
if err != errLast {
|
|
return nil, err
|
|
}
|
|
break
|
|
}
|
|
}
|
|
return containers, nil
|
|
}
|