// DEPRECATION NOTICE. PLEASE DO NOT ADD ANYTHING TO THIS FILE. // // For additional commments see server/server.go // package server import ( "errors" "fmt" "os/exec" "strconv" "strings" "github.com/docker/docker/daemon" "github.com/docker/docker/engine" "github.com/docker/docker/pkg/graphdb" ) func (srv *Server) ContainerTop(job *engine.Job) engine.Status { if len(job.Args) != 1 && len(job.Args) != 2 { return job.Errorf("Not enough arguments. Usage: %s CONTAINER [PS_ARGS]\n", job.Name) } var ( name = job.Args[0] psArgs = "-ef" ) if len(job.Args) == 2 && job.Args[1] != "" { psArgs = job.Args[1] } if container := srv.daemon.Get(name); container != nil { if !container.State.IsRunning() { return job.Errorf("Container %s is not running", name) } pids, err := srv.daemon.ExecutionDriver().GetPidsForContainer(container.ID) if err != nil { return job.Error(err) } output, err := exec.Command("ps", psArgs).Output() if err != nil { return job.Errorf("Error running ps: %s", err) } lines := strings.Split(string(output), "\n") header := strings.Fields(lines[0]) out := &engine.Env{} out.SetList("Titles", header) pidIndex := -1 for i, name := range header { if name == "PID" { pidIndex = i } } if pidIndex == -1 { return job.Errorf("Couldn't find PID field in ps output") } processes := [][]string{} for _, line := range lines[1:] { if len(line) == 0 { continue } fields := strings.Fields(line) p, err := strconv.Atoi(fields[pidIndex]) if err != nil { return job.Errorf("Unexpected pid '%s': %s", fields[pidIndex], err) } for _, pid := range pids { if pid == p { // Make sure number of fields equals number of header titles // merging "overhanging" fields process := fields[:len(header)-1] process = append(process, strings.Join(fields[len(header)-1:], " ")) processes = append(processes, process) } } } out.SetJson("Processes", processes) out.WriteTo(job.Stdout) return engine.StatusOK } return job.Errorf("No such container: %s", name) } func (srv *Server) ContainerChanges(job *engine.Job) engine.Status { if n := len(job.Args); n != 1 { return job.Errorf("Usage: %s CONTAINER", job.Name) } name := job.Args[0] if container := srv.daemon.Get(name); container != nil { outs := engine.NewTable("", 0) changes, err := container.Changes() if err != nil { return job.Error(err) } for _, change := range changes { out := &engine.Env{} if err := out.Import(change); err != nil { return job.Error(err) } outs.Add(out) } if _, err := outs.WriteListTo(job.Stdout); err != nil { return job.Error(err) } } else { return job.Errorf("No such container: %s", name) } return engine.StatusOK } func (srv *Server) 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") ) outs := engine.NewTable("Created", 0) names := map[string][]string{} srv.daemon.ContainerGraph().Walk("/", func(p string, e *graphdb.Entity) error { names[e.ID()] = append(names[e.ID()], p) return nil }, -1) var beforeCont, sinceCont *daemon.Container if before != "" { beforeCont = srv.daemon.Get(before) if beforeCont == nil { return job.Error(fmt.Errorf("Could not find container with name or id %s", before)) } } if since != "" { sinceCont = srv.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 *daemon.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 } } displayed++ out := &engine.Env{} out.Set("Id", container.ID) out.SetList("Names", names[container.ID]) out.Set("Image", srv.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 srv.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 }