func (s *TagStore) CmdImages(job *engine.Job) engine.Status { var ( allImages map[string]*image.Image err error filt_tagged = true ) imageFilters, err := filters.FromParam(job.Getenv("filters")) if err != nil { return job.Error(err) } if i, ok := imageFilters["dangling"]; ok { for _, value := range i { if strings.ToLower(value) == "true" { filt_tagged = false } } } if job.GetenvBool("all") && filt_tagged { allImages, err = s.graph.Map() } else { allImages, err = s.graph.Heads() } if err != nil { return job.Error(err) } lookup := make(map[string]*engine.Env) s.Lock() for name, repository := range s.Repositories { if job.Getenv("filter") != "" { if match, _ := path.Match(job.Getenv("filter"), name); !match { continue } } for tag, id := range repository { image, err := s.graph.Get(id) if err != nil { log.Printf("Warning: couldn't load %s from %s/%s: %s", id, name, tag, err) continue } if out, exists := lookup[id]; exists { if filt_tagged { out.SetList("RepoTags", append(out.GetList("RepoTags"), fmt.Sprintf("%s:%s", name, tag))) } } else { // get the boolean list for if only the untagged images are requested delete(allImages, id) if filt_tagged { out := &engine.Env{} out.Set("ParentId", image.Parent) out.SetList("RepoTags", []string{fmt.Sprintf("%s:%s", name, tag)}) out.Set("Id", image.ID) out.SetInt64("Created", image.Created.Unix()) out.SetInt64("Size", image.Size) out.SetInt64("VirtualSize", image.GetParentsSize(0)+image.Size) lookup[id] = out } } } } s.Unlock() outs := engine.NewTable("Created", len(lookup)) for _, value := range lookup { outs.Add(value) } // Display images which aren't part of a repository/tag if job.Getenv("filter") == "" { for _, image := range allImages { out := &engine.Env{} out.Set("ParentId", image.Parent) out.SetList("RepoTags", []string{"<none>:<none>"}) out.Set("Id", image.ID) out.SetInt64("Created", image.Created.Unix()) out.SetInt64("Size", image.Size) out.SetInt64("VirtualSize", image.GetParentsSize(0)+image.Size) outs.Add(out) } } outs.ReverseSort() if _, err := outs.WriteListTo(job.Stdout); err != nil { return job.Error(err) } return engine.StatusOK }
func (daemon *Daemon) Containers(job *engine.Job) engine.Status { var ( foundBefore bool displayed int all = job.GetenvBool("all") since = job.Getenv("since") before = job.Getenv("before") n = job.GetenvInt("limit") size = job.GetenvBool("size") psFilters filters.Args filt_exited []int ) outs := engine.NewTable("Created", 0) psFilters, err := filters.FromParam(job.Getenv("filters")) if err != nil { return job.Error(err) } if i, ok := psFilters["exited"]; ok { for _, value := range i { code, err := strconv.Atoi(value) if err != nil { return job.Error(err) } filt_exited = append(filt_exited, code) } } 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 before != "" { beforeCont = daemon.Get(before) if beforeCont == nil { return job.Error(fmt.Errorf("Could not find container with name or id %s", before)) } } if since != "" { sinceCont = daemon.Get(since) if sinceCont == nil { return job.Error(fmt.Errorf("Could not find container with name or id %s", since)) } } errLast := errors.New("last container") writeCont := func(container *Container) error { container.Lock() defer container.Unlock() if !container.State.IsRunning() && !all && n <= 0 && since == "" && before == "" { return nil } if before != "" && !foundBefore { if container.ID == beforeCont.ID { foundBefore = true } return nil } if n > 0 && displayed == n { return errLast } if since != "" { if container.ID == sinceCont.ID { return errLast } } if len(filt_exited) > 0 && !container.State.IsRunning() { should_skip := true for _, code := range filt_exited { if code == container.State.GetExitCode() { should_skip = false break } } if should_skip { return nil } } displayed++ out := &engine.Env{} out.Set("Id", container.ID) out.SetList("Names", names[container.ID]) out.Set("Image", daemon.Repositories().ImageName(container.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, " ") out.Set("Command", fmt.Sprintf("\"%s %s\"", container.Path, argsAsString)) } else { out.Set("Command", fmt.Sprintf("\"%s\"", container.Path)) } out.SetInt64("Created", container.Created.Unix()) out.Set("Status", container.State.String()) str, err := container.NetworkSettings.PortMappingAPI().ToListString() if err != nil { return err } out.Set("Ports", str) if size { sizeRw, sizeRootFs := container.GetSize() out.SetInt64("SizeRw", sizeRw) out.SetInt64("SizeRootFs", sizeRootFs) } outs.Add(out) return nil } for _, container := range daemon.List() { if err := writeCont(container); err != nil { if err != errLast { return job.Error(err) } break } } outs.ReverseSort() if _, err := outs.WriteListTo(job.Stdout); err != nil { return job.Error(err) } return engine.StatusOK }