github.com/erriapo/docker@v1.6.0-rc2/daemon/list.go (about)

     1  package daemon
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  
     9  	"github.com/docker/docker/graph"
    10  	"github.com/docker/docker/pkg/graphdb"
    11  	"github.com/docker/docker/utils"
    12  
    13  	"github.com/docker/docker/engine"
    14  	"github.com/docker/docker/pkg/parsers"
    15  	"github.com/docker/docker/pkg/parsers/filters"
    16  )
    17  
    18  // List returns an array of all containers registered in the daemon.
    19  func (daemon *Daemon) List() []*Container {
    20  	return daemon.containers.List()
    21  }
    22  
    23  func (daemon *Daemon) Containers(job *engine.Job) engine.Status {
    24  	var (
    25  		foundBefore bool
    26  		displayed   int
    27  		all         = job.GetenvBool("all")
    28  		since       = job.Getenv("since")
    29  		before      = job.Getenv("before")
    30  		n           = job.GetenvInt("limit")
    31  		size        = job.GetenvBool("size")
    32  		psFilters   filters.Args
    33  		filt_exited []int
    34  	)
    35  	outs := engine.NewTable("Created", 0)
    36  
    37  	psFilters, err := filters.FromParam(job.Getenv("filters"))
    38  	if err != nil {
    39  		return job.Error(err)
    40  	}
    41  	if i, ok := psFilters["exited"]; ok {
    42  		for _, value := range i {
    43  			code, err := strconv.Atoi(value)
    44  			if err != nil {
    45  				return job.Error(err)
    46  			}
    47  			filt_exited = append(filt_exited, code)
    48  		}
    49  	}
    50  
    51  	if i, ok := psFilters["status"]; ok {
    52  		for _, value := range i {
    53  			if value == "exited" {
    54  				all = true
    55  			}
    56  		}
    57  	}
    58  	names := map[string][]string{}
    59  	daemon.ContainerGraph().Walk("/", func(p string, e *graphdb.Entity) error {
    60  		names[e.ID()] = append(names[e.ID()], p)
    61  		return nil
    62  	}, 1)
    63  
    64  	var beforeCont, sinceCont *Container
    65  	if before != "" {
    66  		beforeCont, err = daemon.Get(before)
    67  		if err != nil {
    68  			return job.Error(err)
    69  		}
    70  	}
    71  
    72  	if since != "" {
    73  		sinceCont, err = daemon.Get(since)
    74  		if err != nil {
    75  			return job.Error(err)
    76  		}
    77  	}
    78  
    79  	errLast := errors.New("last container")
    80  	writeCont := func(container *Container) error {
    81  		container.Lock()
    82  		defer container.Unlock()
    83  		if !container.Running && !all && n <= 0 && since == "" && before == "" {
    84  			return nil
    85  		}
    86  		if !psFilters.Match("name", container.Name) {
    87  			return nil
    88  		}
    89  
    90  		if !psFilters.Match("id", container.ID) {
    91  			return nil
    92  		}
    93  
    94  		if !psFilters.MatchKVList("label", container.Config.Labels) {
    95  			return nil
    96  		}
    97  
    98  		if before != "" && !foundBefore {
    99  			if container.ID == beforeCont.ID {
   100  				foundBefore = true
   101  			}
   102  			return nil
   103  		}
   104  		if n > 0 && displayed == n {
   105  			return errLast
   106  		}
   107  		if since != "" {
   108  			if container.ID == sinceCont.ID {
   109  				return errLast
   110  			}
   111  		}
   112  		if len(filt_exited) > 0 {
   113  			should_skip := true
   114  			for _, code := range filt_exited {
   115  				if code == container.ExitCode && !container.Running {
   116  					should_skip = false
   117  					break
   118  				}
   119  			}
   120  			if should_skip {
   121  				return nil
   122  			}
   123  		}
   124  
   125  		if !psFilters.Match("status", container.State.StateString()) {
   126  			return nil
   127  		}
   128  		displayed++
   129  		out := &engine.Env{}
   130  		out.SetJson("Id", container.ID)
   131  		out.SetList("Names", names[container.ID])
   132  		img := container.Config.Image
   133  		_, tag := parsers.ParseRepositoryTag(container.Config.Image)
   134  		if tag == "" {
   135  			img = utils.ImageReference(img, graph.DEFAULTTAG)
   136  		}
   137  		out.SetJson("Image", img)
   138  		if len(container.Args) > 0 {
   139  			args := []string{}
   140  			for _, arg := range container.Args {
   141  				if strings.Contains(arg, " ") {
   142  					args = append(args, fmt.Sprintf("'%s'", arg))
   143  				} else {
   144  					args = append(args, arg)
   145  				}
   146  			}
   147  			argsAsString := strings.Join(args, " ")
   148  
   149  			out.Set("Command", fmt.Sprintf("\"%s %s\"", container.Path, argsAsString))
   150  		} else {
   151  			out.Set("Command", fmt.Sprintf("\"%s\"", container.Path))
   152  		}
   153  		out.SetInt64("Created", container.Created.Unix())
   154  		out.Set("Status", container.State.String())
   155  		str, err := container.NetworkSettings.PortMappingAPI().ToListString()
   156  		if err != nil {
   157  			return err
   158  		}
   159  		out.Set("Ports", str)
   160  		if size {
   161  			sizeRw, sizeRootFs := container.GetSize()
   162  			out.SetInt64("SizeRw", sizeRw)
   163  			out.SetInt64("SizeRootFs", sizeRootFs)
   164  		}
   165  		out.SetJson("Labels", container.Config.Labels)
   166  		outs.Add(out)
   167  		return nil
   168  	}
   169  
   170  	for _, container := range daemon.List() {
   171  		if err := writeCont(container); err != nil {
   172  			if err != errLast {
   173  				return job.Error(err)
   174  			}
   175  			break
   176  		}
   177  	}
   178  	outs.ReverseSort()
   179  	if _, err := outs.WriteListTo(job.Stdout); err != nil {
   180  		return job.Error(err)
   181  	}
   182  	return engine.StatusOK
   183  }