Stats displays a live stream of container(s) resource usage statistics.
(ctx context.Context, client *containerd.Client, containerIDs []string, options types.ContainerStatsOptions)
| 83 | |
| 84 | // Stats displays a live stream of container(s) resource usage statistics. |
| 85 | func Stats(ctx context.Context, client *containerd.Client, containerIDs []string, options types.ContainerStatsOptions) error { |
| 86 | // NOTE: rootless container does not rely on cgroupv1. |
| 87 | // more details about possible ways to resolve this concern: #223 |
| 88 | if rootlessutil.IsRootless() && infoutil.CgroupsVersion() == "1" { |
| 89 | return errors.New("stats requires cgroup v2 for rootless containers, see https://rootlesscontaine.rs/getting-started/common/cgroup2/") |
| 90 | } |
| 91 | |
| 92 | showAll := len(containerIDs) == 0 |
| 93 | closeChan := make(chan error) |
| 94 | |
| 95 | var err error |
| 96 | w := options.Stdout |
| 97 | var tmpl *template.Template |
| 98 | switch options.Format { |
| 99 | case "", "table": |
| 100 | w = tabwriter.NewWriter(options.Stdout, 10, 1, 3, ' ', 0) |
| 101 | case "raw": |
| 102 | return errors.New("unsupported format: \"raw\"") |
| 103 | default: |
| 104 | tmpl, err = formatter.ParseTemplate(options.Format) |
| 105 | if err != nil { |
| 106 | return err |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | // waitFirst is a WaitGroup to wait first stat data's reach for each container |
| 111 | waitFirst := &sync.WaitGroup{} |
| 112 | cStats := stats{} |
| 113 | |
| 114 | monitorContainerEvents := func(started chan<- struct{}, c chan *events.Envelope, closeEventChan chan struct{}) { |
| 115 | eventsClient := client.EventService() |
| 116 | eventsCh, errCh := eventsClient.Subscribe(ctx) |
| 117 | |
| 118 | // Whether we successfully subscribed to eventsCh or not, we can now |
| 119 | // unblock the main goroutine. |
| 120 | close(started) |
| 121 | |
| 122 | for { |
| 123 | select { |
| 124 | case <-closeEventChan: |
| 125 | // c is closed, so we can stop monitoring events |
| 126 | return |
| 127 | case event := <-eventsCh: |
| 128 | c <- event |
| 129 | case err = <-errCh: |
| 130 | closeChan <- err |
| 131 | return |
| 132 | } |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | // getContainerList get all existing containers (only used when calling `nerdctl stats` without arguments). |
| 137 | getContainerList := func() { |
| 138 | containers, err := client.Containers(ctx) |
| 139 | if err != nil { |
| 140 | closeChan <- err |
| 141 | } |
| 142 |
no test coverage detected
searching dependent graphs…