@@ -12,6 +12,7 @@ import (
1212 "time"
1313
1414 apitypes "github.com/alibaba/pouch/apis/types"
15+ "github.com/alibaba/pouch/ctrd"
1516 "github.com/alibaba/pouch/daemon/config"
1617 "github.com/alibaba/pouch/daemon/mgr"
1718 "github.com/alibaba/pouch/pkg/errtypes"
@@ -60,6 +61,15 @@ const (
6061
6162 // resolvConfPath is the abs path of resolv.conf on host or container.
6263 resolvConfPath = "/etc/resolv.conf"
64+
65+ // statsCollectPeriod is the time duration we sync stats from containerd.
66+ statsCollectPeriod = 10
67+
68+ // defaultSnapshotterName is the default Snapshotter name.
69+ defaultSnapshotterName = "overlayfs"
70+
71+ // snapshotPlugin implements a snapshotter.
72+ snapshotPlugin = "io.containerd.snapshotter.v1"
6373)
6474
6575var (
@@ -85,6 +95,9 @@ type CriManager struct {
8595 ImageMgr mgr.ImageMgr
8696 CniMgr CniMgr
8797
98+ // Client is used to interact with containerd.
99+ Client ctrd.APIClient
100+
88101 // StreamServer is the stream server of CRI serves container streaming request.
89102 StreamServer Server
90103
@@ -95,10 +108,16 @@ type CriManager struct {
95108 SandboxImage string
96109 // SandboxStore stores the configuration of sandboxes.
97110 SandboxStore * meta.Store
111+
112+ // SnapshotStore stores information of all snapshots.
113+ SnapshotStore * mgr.SnapshotStore
114+
115+ // ImageFSUUID is the device uuid of image filesystem.
116+ ImageFSUUID string
98117}
99118
100119// NewCriManager creates a brand new cri manager.
101- func NewCriManager (config * config.Config , ctrMgr mgr.ContainerMgr , imgMgr mgr.ImageMgr ) (CriMgr , error ) {
120+ func NewCriManager (config * config.Config , cli ctrd. APIClient , ctrMgr mgr.ContainerMgr , imgMgr mgr.ImageMgr ) (CriMgr , error ) {
102121 streamServer , err := newStreamServer (ctrMgr , streamServerAddress , streamServerPort )
103122 if err != nil {
104123 return nil , fmt .Errorf ("failed to create stream server for cri manager: %v" , err )
@@ -108,9 +127,11 @@ func NewCriManager(config *config.Config, ctrMgr mgr.ContainerMgr, imgMgr mgr.Im
108127 ContainerMgr : ctrMgr ,
109128 ImageMgr : imgMgr ,
110129 CniMgr : NewCniManager (& config .CriConfig ),
130+ Client : cli ,
111131 StreamServer : streamServer ,
112132 SandboxBaseDir : path .Join (config .HomeDir , "sandboxes" ),
113133 SandboxImage : config .CriConfig .SandboxImage ,
134+ SnapshotStore : mgr .NewSnapshotStore (),
114135 }
115136
116137 c .SandboxStore , err = meta .NewStore (meta.Config {
@@ -127,6 +148,19 @@ func NewCriManager(config *config.Config, ctrMgr mgr.ContainerMgr, imgMgr mgr.Im
127148 return nil , fmt .Errorf ("failed to create sandbox meta store: %v" , err )
128149 }
129150
151+ imageFSPath := imageFSPath (path .Join (config .HomeDir , "containerd/root" ), defaultSnapshotterName )
152+ c .ImageFSUUID , err = getDeviceUUID (imageFSPath )
153+ if err != nil {
154+ return nil , fmt .Errorf ("failed to get imagefs uuid of %q: %v" , imageFSPath , err )
155+ }
156+
157+ snapshotsSyncer := mgr .NewSnapshotsSyncer (
158+ c .SnapshotStore ,
159+ c .Client ,
160+ time .Duration (statsCollectPeriod )* time .Second ,
161+ )
162+ snapshotsSyncer .Start ()
163+
130164 return NewCriWrapper (c ), nil
131165}
132166
@@ -679,12 +713,55 @@ func (c *CriManager) ContainerStatus(ctx context.Context, r *runtime.ContainerSt
679713// ContainerStats returns stats of the container. If the container does not
680714// exist, the call returns an error.
681715func (c * CriManager ) ContainerStats (ctx context.Context , r * runtime.ContainerStatsRequest ) (* runtime.ContainerStatsResponse , error ) {
682- return nil , fmt .Errorf ("ContainerStats Not Implemented Yet" )
716+ containerID := r .GetContainerId ()
717+
718+ container , err := c .ContainerMgr .Get (ctx , containerID )
719+ if err != nil {
720+ return nil , fmt .Errorf ("failed to get container %q with error: %v" , containerID , err )
721+ }
722+
723+ stats , err := c .ContainerMgr .Stats (ctx , containerID )
724+ if err != nil {
725+ return nil , fmt .Errorf ("failed to get stats of container %q with error: %v" , containerID , err )
726+ }
727+
728+ cs , err := c .getContainerMetrics (container , stats )
729+ if err != nil {
730+ return nil , fmt .Errorf ("failed to decode container metrics: %v" , err )
731+ }
732+
733+ return & runtime.ContainerStatsResponse {Stats : cs }, nil
683734}
684735
685736// ListContainerStats returns stats of all running containers.
686737func (c * CriManager ) ListContainerStats (ctx context.Context , r * runtime.ListContainerStatsRequest ) (* runtime.ListContainerStatsResponse , error ) {
687- return nil , fmt .Errorf ("ListContainerStats Not Implemented Yet" )
738+ opts := & mgr.ContainerListOption {All : true }
739+ filter := func (c * mgr.Container ) bool {
740+ return true
741+ }
742+ containers , err := c .ContainerMgr .List (ctx , filter , opts )
743+ if err != nil {
744+ return nil , fmt .Errorf ("failed to list containers: %v" , err )
745+ }
746+
747+ result := & runtime.ListContainerStatsResponse {}
748+ for _ , container := range containers {
749+ stats , err := c .ContainerMgr .Stats (ctx , container .ID )
750+ if err != nil {
751+ logrus .Errorf ("failed to get stats of container %q: %v" , container .ID , err )
752+ continue
753+ }
754+
755+ cs , err := c .getContainerMetrics (container , stats )
756+ if err != nil {
757+ logrus .Errorf ("failed to decode metrics of container %q: %v" , container .ID , err )
758+ continue
759+ }
760+
761+ result .Stats = append (result .Stats , cs )
762+ }
763+
764+ return result , nil
688765}
689766
690767// UpdateContainerResources updates ContainerConfig of the container.
@@ -907,5 +984,25 @@ func (c *CriManager) RemoveImage(ctx context.Context, r *runtime.RemoveImageRequ
907984
908985// ImageFsInfo returns information of the filesystem that is used to store images.
909986func (c * CriManager ) ImageFsInfo (ctx context.Context , r * runtime.ImageFsInfoRequest ) (* runtime.ImageFsInfoResponse , error ) {
910- return nil , fmt .Errorf ("ImageFsInfo Not Implemented Yet" )
987+ snapshots := c .SnapshotStore .List ()
988+ timestamp := time .Now ().UnixNano ()
989+ var usedBytes , inodesUsed uint64
990+ for _ , sn := range snapshots {
991+ // Use the oldest timestamp as the timestamp of imagefs info.
992+ if sn .Timestamp < timestamp {
993+ timestamp = sn .Timestamp
994+ }
995+ usedBytes += sn .Size
996+ inodesUsed += sn .Inodes
997+ }
998+ return & runtime.ImageFsInfoResponse {
999+ ImageFilesystems : []* runtime.FilesystemUsage {
1000+ {
1001+ Timestamp : timestamp ,
1002+ StorageId : & runtime.StorageIdentifier {Uuid : c .ImageFSUUID },
1003+ UsedBytes : & runtime.UInt64Value {Value : usedBytes },
1004+ InodesUsed : & runtime.UInt64Value {Value : inodesUsed },
1005+ },
1006+ },
1007+ }, nil
9111008}
0 commit comments