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  }