@@ -34,7 +34,19 @@ constexpr const std::string_view CONTAINERD_SOCKETS[] = {
3434};
3535
3636bool containerd_async_source::is_ok () {
37- return m_stub != nullptr ;
37+ return m_container_stub != nullptr && m_image_stub != nullptr ;
38+ }
39+
40+ static inline void setup_grpc_client_context (grpc::ClientContext &context) {
41+ auto deadline = std::chrono::system_clock::now () +
42+ std::chrono::milliseconds (libsinsp::cri::cri_settings::get_cri_timeout ());
43+
44+ context.set_deadline (deadline);
45+
46+ // The `default` namesapce is the default one of containerd
47+ // and the one used by host-containers in bottlerocket.
48+ // This is mandatory to query the containers.
49+ context.AddMetadata (" containerd-namespace" , " default" );
3850}
3951
4052containerd_async_source::containerd_async_source (const std::string &socket_path,
@@ -47,30 +59,50 @@ containerd_async_source::containerd_async_source(const std::string &socket_path,
4759 std::shared_ptr<grpc::Channel> channel =
4860 libsinsp::grpc_channel_registry::get_channel (" unix://" + socket_path, &args);
4961
50- m_stub = ContainerdService::Containers::NewStub (channel);
62+ // Check the status of the container stub.
63+ {
64+ grpc::ClientContext context;
65+ setup_grpc_client_context (context);
5166
52- ContainerdService::ListContainersRequest req;
53- ContainerdService::ListContainersResponse resp;
67+ m_container_stub = ContainerdContainerService::Containers::NewStub (channel);
5468
55- grpc::ClientContext context;
56- auto deadline = std::chrono::system_clock::now () +
57- std::chrono::milliseconds (libsinsp::cri::cri_settings::get_cri_timeout ());
58- context.set_deadline (deadline);
69+ ContainerdContainerService::ListContainersRequest req;
70+ ContainerdContainerService::ListContainersResponse resp;
5971
60- // The `default` namesapce is the default one of containerd
61- // and the one used by host-containers in bottlerocket.
62- // This is mandatory to query the containers.
63- context.AddMetadata (" containerd-namespace" , " default" );
64- grpc::Status status = m_stub->List (&context, req, &resp);
72+ grpc::Status status = m_container_stub->List (&context, req, &resp);
6573
66- if (!status.ok ()) {
67- libsinsp_logger ()->format (sinsp_logger::SEV_NOTICE,
68- " containerd (%s): containerd runtime returned an error after "
69- " trying to list containerd: %s" ,
70- socket_path.c_str (),
71- status.error_message ().c_str ());
72- m_stub.reset (nullptr );
73- return ;
74+ if (!status.ok ()) {
75+ libsinsp_logger ()->format (sinsp_logger::SEV_NOTICE,
76+ " containerd (%s): containerd runtime returned an error after "
77+ " trying to list containers: %s" ,
78+ socket_path.c_str (),
79+ status.error_message ().c_str ());
80+ m_container_stub.reset (nullptr );
81+ return ;
82+ }
83+ }
84+
85+ // Check the status of the image stub.
86+ {
87+ grpc::ClientContext context;
88+ setup_grpc_client_context (context);
89+
90+ m_image_stub = ContainerdImageService::Images::NewStub (channel);
91+
92+ ContainerdImageService::ListImagesRequest req;
93+ ContainerdImageService::ListImagesResponse resp;
94+
95+ grpc::Status status = m_image_stub->List (&context, req, &resp);
96+
97+ if (!status.ok ()) {
98+ libsinsp_logger ()->format (sinsp_logger::SEV_NOTICE,
99+ " containerd (%s): containerd runtime returned an error after "
100+ " trying to list images: %s" ,
101+ socket_path.c_str (),
102+ status.error_message ().c_str ());
103+ m_image_stub.reset (nullptr );
104+ return ;
105+ }
74106 }
75107}
76108
@@ -81,8 +113,8 @@ containerd_async_source::~containerd_async_source() {
81113
82114grpc::Status containerd_async_source::list_container_resp (
83115 const std::string &container_id,
84- ContainerdService ::ListContainersResponse &resp) {
85- ContainerdService ::ListContainersRequest req;
116+ ContainerdContainerService ::ListContainersResponse &resp) {
117+ ContainerdContainerService ::ListContainersRequest req;
86118
87119 // To match the container using a truncated containerd id
88120 // we need to use a match filter (~=).
@@ -92,7 +124,21 @@ grpc::Status containerd_async_source::list_container_resp(
92124 auto deadline = std::chrono::system_clock::now () +
93125 std::chrono::milliseconds (libsinsp::cri::cri_settings::get_cri_timeout ());
94126 context.set_deadline (deadline);
95- return m_stub->List (&context, req, &resp);
127+ return m_container_stub->List (&context, req, &resp);
128+ }
129+
130+ grpc::Status containerd_async_source::get_image_resp (
131+ const std::string &image_name,
132+ ContainerdImageService::GetImageResponse &resp) {
133+ ContainerdImageService::GetImageRequest req;
134+
135+ req.set_name (image_name);
136+ grpc::ClientContext context;
137+ context.AddMetadata (" containerd-namespace" , " default" );
138+ auto deadline = std::chrono::system_clock::now () +
139+ std::chrono::milliseconds (libsinsp::cri::cri_settings::get_cri_timeout ());
140+ context.set_deadline (deadline);
141+ return m_image_stub->Get (&context, req, &resp);
96142}
97143
98144libsinsp::container_engine::containerd::containerd (container_cache_interface &cache):
@@ -132,7 +178,7 @@ bool containerd_async_source::parse(const containerd_lookup_request &request,
132178
133179 // given the truncated container id, the full container id needs to be retrivied from
134180 // containerd.
135- ContainerdService ::ListContainersResponse resp;
181+ ContainerdContainerService ::ListContainersResponse resp;
136182 grpc::Status status = list_container_resp (container_id, resp);
137183
138184 if (!status.ok ()) {
@@ -174,9 +220,23 @@ bool containerd_async_source::parse(const containerd_lookup_request &request,
174220 // and the first part is the repo
175221 container.m_imagerepo = raw_image_splits[0 ].substr (0 , raw_image_splits[0 ].rfind (" /" ));
176222 container.m_imagetag = raw_image_splits[1 ];
177- container.m_imagedigest = " " ;
178223 container.m_type = CT_CONTAINERD;
179224
225+ // Retrieve the image digest.
226+ ContainerdImageService::GetImageResponse img_resp;
227+ status = get_image_resp (containers[0 ].image (), img_resp);
228+
229+ if (!status.ok ()) {
230+ libsinsp_logger ()->format (sinsp_logger::SEV_DEBUG,
231+ " containerd (%s): GetImageResponse status error message: (%s)" ,
232+ container.m_id .c_str (),
233+ status.error_message ().c_str ());
234+
235+ // Don't exit given that we have part of the needed information.
236+ }
237+
238+ container.m_imagedigest = img_resp.image ().target ().digest ();
239+
180240 // Retrieve the labels.
181241 for (const auto &pair : containers[0 ].labels ()) {
182242 if (pair.second .length () <= sinsp_container_info::m_container_label_max_length) {
0 commit comments