list.go#Action

  1. Action: func(context *cli.Context) error {
  2. if err := checkArgs(context, 0, exactArgs); err != nil {
  3. return err
  4. }
  5. // ********************************** NOTICE ********************************** //
  6. s, err := getContainers(context)
  7. // ********************************** NOTICE ********************************** //
  8. if err != nil {
  9. return err
  10. }
  11. if context.Bool("quiet") {
  12. for _, item := range s {
  13. fmt.Println(item.ID)
  14. }
  15. return nil
  16. }
  17. switch context.String("format") {
  18. case "table":
  19. w := tabwriter.NewWriter(os.Stdout, 12, 1, 3, ' ', 0)
  20. fmt.Fprint(w, "ID\tPID\tSTATUS\tBUNDLE\tCREATED\tOWNER\n")
  21. for _, item := range s {
  22. fmt.Fprintf(w, "%s\t%d\t%s\t%s\t%s\t%s\n",
  23. item.ID,
  24. item.InitProcessPid,
  25. item.Status,
  26. item.Bundle,
  27. item.Created.Format(time.RFC3339Nano),
  28. item.Owner)
  29. }
  30. if err := w.Flush(); err != nil {
  31. return err
  32. }
  33. case "json":
  34. if err := json.NewEncoder(os.Stdout).Encode(s); err != nil {
  35. return err
  36. }
  37. default:
  38. return fmt.Errorf("invalid format option")
  39. }
  40. return nil
  41. },

1) list.go#getContainers

  1. func getContainers(context *cli.Context) ([]containerState, error) {
  2. factory, err := loadFactory(context)
  3. if err != nil {
  4. return nil, err
  5. }
  6. root := context.GlobalString("root")
  7. absRoot, err := filepath.Abs(root)
  8. if err != nil {
  9. return nil, err
  10. }
  11. list, err := ioutil.ReadDir(absRoot)
  12. if err != nil {
  13. fatal(err)
  14. }
  15. var s []containerState
  16. for _, item := range list {
  17. if item.IsDir() {
  18. // This cast is safe on Linux.
  19. stat := item.Sys().(*syscall.Stat_t)
  20. owner, err := user.LookupUid(int(stat.Uid))
  21. if err != nil {
  22. owner.Name = fmt.Sprintf("#%d", stat.Uid)
  23. }
  24. // ********************************** NOTICE ******************************** //
  25. container, err := factory.Load(item.Name())
  26. // ********************************** NOTICE ******************************** //
  27. if err != nil {
  28. fmt.Fprintf(os.Stderr, "load container %s: %v\n", item.Name(), err)
  29. continue
  30. }
  31. containerStatus, err := container.Status()
  32. if err != nil {
  33. fmt.Fprintf(os.Stderr, "status for %s: %v\n", item.Name(), err)
  34. continue
  35. }
  36. state, err := container.State()
  37. if err != nil {
  38. fmt.Fprintf(os.Stderr, "state for %s: %v\n", item.Name(), err)
  39. continue
  40. }
  41. pid := state.BaseState.InitProcessPid
  42. if containerStatus == libcontainer.Stopped {
  43. pid = 0
  44. }
  45. bundle, annotations := utils.Annotations(state.Config.Labels)
  46. s = append(s, containerState{
  47. Version: state.BaseState.Config.Version,
  48. ID: state.BaseState.ID,
  49. InitProcessPid: pid,
  50. Status: containerStatus.String(),
  51. Bundle: bundle,
  52. Rootfs: state.BaseState.Config.Rootfs,
  53. Created: state.BaseState.Created,
  54. Annotations: annotations,
  55. Owner: owner.Name,
  56. })
  57. }
  58. }
  59. return s, nil
  60. }