github.com/daaku/docker@v1.5.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/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  	if i, ok := psFilters["status"]; ok {
    49  		for _, value := range i {
    50  			if value == "exited" {
    51  				all = true
    52  			}
    53  		}
    54  	}
    55  
    56  	names := map[string][]string{}
    57  	daemon.ContainerGraph().Walk("/", func(p string, e *graphdb.Entity) error {
    58  		names[e.ID()] = append(names[e.ID()], p)
    59  		return nil
    60  	}, -1)
    61  
    62  	var beforeCont, sinceCont *Container
    63  	if before != "" {
    64  		beforeCont = daemon.Get(before)
    65  		if beforeCont == nil {
    66  			return job.Error(fmt.Errorf("Could not find container with name or id %s", before))
    67  		}
    68  	}
    69  
    70  	if since != "" {
    71  		sinceCont = daemon.Get(since)
    72  		if sinceCont == nil {
    73  			return job.Error(fmt.Errorf("Could not find container with name or id %s", since))
    74  		}
    75  	}
    76  
    77  	errLast := errors.New("last container")
    78  	writeCont := func(container *Container) error {
    79  		container.Lock()
    80  		defer container.Unlock()
    81  		if !container.Running && !all && n <= 0 && since == "" && before == "" {
    82  			return nil
    83  		}
    84  		if !psFilters.Match("name", container.Name) {
    85  			return nil
    86  		}
    87  
    88  		if !psFilters.Match("id", container.ID) {
    89  			return nil
    90  		}
    91  
    92  		if before != "" && !foundBefore {
    93  			if container.ID == beforeCont.ID {
    94  				foundBefore = true
    95  			}
    96  			return nil
    97  		}
    98  		if n > 0 && displayed == n {
    99  			return errLast
   100  		}
   101  		if since != "" {
   102  			if container.ID == sinceCont.ID {
   103  				return errLast
   104  			}
   105  		}
   106  		if len(filt_exited) > 0 {
   107  			should_skip := true
   108  			for _, code := range filt_exited {
   109  				if code == container.ExitCode && !container.Running {
   110  					should_skip = false
   111  					break
   112  				}
   113  			}
   114  			if should_skip {
   115  				return nil
   116  			}
   117  		}
   118  
   119  		if !psFilters.Match("status", container.State.StateString()) {
   120  			return nil
   121  		}
   122  		displayed++
   123  		out := &engine.Env{}
   124  		out.SetJson("Id", container.ID)
   125  		out.SetList("Names", names[container.ID])
   126  		out.SetJson("Image", daemon.Repositories().ImageName(container.ImageID))
   127  		if len(container.Args) > 0 {
   128  			args := []string{}
   129  			for _, arg := range container.Args {
   130  				if strings.Contains(arg, " ") {
   131  					args = append(args, fmt.Sprintf("'%s'", arg))
   132  				} else {
   133  					args = append(args, arg)
   134  				}
   135  			}
   136  			argsAsString := strings.Join(args, " ")
   137  
   138  			out.Set("Command", fmt.Sprintf("\"%s %s\"", container.Path, argsAsString))
   139  		} else {
   140  			out.Set("Command", fmt.Sprintf("\"%s\"", container.Path))
   141  		}
   142  		out.SetInt64("Created", container.Created.Unix())
   143  		out.Set("Status", container.State.String())
   144  		str, err := container.NetworkSettings.PortMappingAPI().ToListString()
   145  		if err != nil {
   146  			return err
   147  		}
   148  		out.Set("Ports", str)
   149  		if size {
   150  			sizeRw, sizeRootFs := container.GetSize()
   151  			out.SetInt64("SizeRw", sizeRw)
   152  			out.SetInt64("SizeRootFs", sizeRootFs)
   153  		}
   154  		outs.Add(out)
   155  		return nil
   156  	}
   157  
   158  	for _, container := range daemon.List() {
   159  		if err := writeCont(container); err != nil {
   160  			if err != errLast {
   161  				return job.Error(err)
   162  			}
   163  			break
   164  		}
   165  	}
   166  	outs.ReverseSort()
   167  	if _, err := outs.WriteListTo(job.Stdout); err != nil {
   168  		return job.Error(err)
   169  	}
   170  	return engine.StatusOK
   171  }