Compare commits

...

7 Commits

Author SHA1 Message Date
Federico Di Pierro 5a5709133d chore(ci): switch to github-provided arm64 runners.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-01-17 10:48:32 +01:00
Leonardo Grasso 1510ea322f docs(userspace/libsinsp/filter/parser): fix grammar doc
The spaces after the operator tokens were intended to indicate operators that mandate a whitespace character to be followed.

Co-authored-by: Jason Dellaluce <jasondellaluce@gmail.com>
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-01-17 10:48:32 +01:00
Roberto Scolaro 1a577bac89 chore(libsinsp/runc): report correct container id with short cid
Signed-off-by: Roberto Scolaro <roberto.scolaro21@gmail.com>
2025-01-17 10:48:32 +01:00
Leonardo Grasso 0297142814 docs(userspace/libsinsp/filter/parser): update grammar doc
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-01-17 10:48:32 +01:00
Roberto Scolaro dfd4328260 fix(libsinsp/container_engine/containerd): avoid cache confusion between containerd sockets
Signed-off-by: Roberto Scolaro <roberto.scolaro21@gmail.com>
2025-01-17 10:48:32 +01:00
Roberto Scolaro ba990bce80 fix(libsinsp/runc): use old logic and fallback for containerd
Signed-off-by: Roberto Scolaro <roberto.scolaro21@gmail.com>
2025-01-17 10:48:32 +01:00
Roberto Scolaro 769dbb023c feat(containers): add host-containerd socket
Signed-off-by: Roberto Scolaro <roberto.scolaro21@gmail.com>
2025-01-17 10:48:32 +01:00
10 changed files with 58 additions and 49 deletions

View File

@ -16,7 +16,7 @@ concurrency:
jobs: jobs:
build-libs-linux: build-libs-linux:
name: build-libs-linux-${{ matrix.arch }} 😁 (${{ matrix.name }}) name: build-libs-linux-${{ matrix.arch }} 😁 (${{ matrix.name }})
runs-on: ${{ (matrix.arch == 'arm64' && 'github-arm64-2c-8gb') || 'ubuntu-22.04' }} runs-on: ${{ (matrix.arch == 'arm64' && 'ubuntu-22.04-arm') || 'ubuntu-22.04' }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:

View File

@ -39,7 +39,7 @@ jobs:
# This job run all engine tests and scap-open # This job run all engine tests and scap-open
test-scap: test-scap:
name: test-scap-${{ matrix.arch }} 😆 (bundled_deps) name: test-scap-${{ matrix.arch }} 😆 (bundled_deps)
runs-on: ${{ (matrix.arch == 'arm64' && 'github-arm64-2c-8gb') || 'ubuntu-22.04' }} runs-on: ${{ (matrix.arch == 'arm64' && 'ubuntu-22.04-arm') || 'ubuntu-22.04' }}
needs: paths-filter needs: paths-filter
strategy: strategy:
matrix: matrix:
@ -104,7 +104,7 @@ jobs:
test-drivers: test-drivers:
name: test-drivers-${{ matrix.arch }} 😇 (bundled_deps) name: test-drivers-${{ matrix.arch }} 😇 (bundled_deps)
runs-on: ${{ (matrix.arch == 'arm64' && 'github-arm64-2c-8gb') || 'ubuntu-22.04' }} runs-on: ${{ (matrix.arch == 'arm64' && 'ubuntu-22.04-arm') || 'ubuntu-22.04' }}
needs: paths-filter needs: paths-filter
strategy: strategy:
matrix: matrix:

View File

@ -15,7 +15,7 @@ concurrency:
jobs: jobs:
build-test-e2e: build-test-e2e:
name: build-test-e2e-${{ matrix.arch }} 😇 (bundled_deps) name: build-test-e2e-${{ matrix.arch }} 😇 (bundled_deps)
runs-on: ${{ (matrix.arch == 'arm64' && 'github-arm64-2c-8gb') || 'ubuntu-22.04' }} runs-on: ${{ (matrix.arch == 'arm64' && 'ubuntu-22.04-arm') || 'ubuntu-22.04' }}
strategy: strategy:
matrix: matrix:
arch: [amd64, arm64] arch: [amd64, arm64]
@ -105,7 +105,7 @@ jobs:
test-e2e: test-e2e:
name: test-e2e-${{ matrix.arch }}-${{ matrix.driver.name }} 😇 (bundled_deps) name: test-e2e-${{ matrix.arch }}-${{ matrix.driver.name }} 😇 (bundled_deps)
needs: [build-test-e2e] needs: [build-test-e2e]
runs-on: ${{ (matrix.arch == 'arm64' && 'github-arm64-2c-8gb') || 'ubuntu-22.04' }} runs-on: ${{ (matrix.arch == 'arm64' && 'ubuntu-22.04-arm') || 'ubuntu-22.04' }}
strategy: strategy:
matrix: matrix:
arch: [amd64, arm64] arch: [amd64, arm64]

View File

@ -78,7 +78,7 @@ jobs:
needs: 'compute-latest-version' needs: 'compute-latest-version'
outputs: outputs:
build: ${{ steps.build.outcome }} build: ${{ steps.build.outcome }}
runs-on: 'github-arm64-2c-8gb' runs-on: 'ubuntu-22.04-arm'
steps: steps:
- name: Download driverkit config - name: Download driverkit config
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8

View File

@ -569,6 +569,7 @@ void sinsp_container_manager::create_engines() {
m_container_engine_by_type[CT_DOCKER].push_back(docker_engine); m_container_engine_by_type[CT_DOCKER].push_back(docker_engine);
} }
size_t engine_index = 0;
if(m_container_engine_mask & ((1 << CT_CRI) | (1 << CT_CRIO) | (1 << CT_CONTAINERD))) { if(m_container_engine_mask & ((1 << CT_CRI) | (1 << CT_CRIO) | (1 << CT_CONTAINERD))) {
// Get CRI socket paths from settings // Get CRI socket paths from settings
libsinsp::cri::cri_settings& cri_settings = libsinsp::cri::cri_settings::get(); libsinsp::cri::cri_settings& cri_settings = libsinsp::cri::cri_settings::get();
@ -577,17 +578,18 @@ void sinsp_container_manager::create_engines() {
cri_settings.add_cri_unix_socket_path("/run/containerd/containerd.sock"); cri_settings.add_cri_unix_socket_path("/run/containerd/containerd.sock");
cri_settings.add_cri_unix_socket_path("/run/crio/crio.sock"); cri_settings.add_cri_unix_socket_path("/run/crio/crio.sock");
cri_settings.add_cri_unix_socket_path("/run/k3s/containerd/containerd.sock"); cri_settings.add_cri_unix_socket_path("/run/k3s/containerd/containerd.sock");
cri_settings.add_cri_unix_socket_path("/run/host-containerd/containerd.sock");
} }
const auto& cri_socket_paths = cri_settings.get_cri_unix_socket_paths(); const auto& cri_socket_paths = cri_settings.get_cri_unix_socket_paths();
size_t engine_index = 0;
for(auto socket_path : cri_socket_paths) { for(auto socket_path : cri_socket_paths) {
auto cri_engine = auto cri_engine =
std::make_shared<container_engine::cri>(*this, socket_path, engine_index); std::make_shared<container_engine::cri>(*this, socket_path, engine_index);
m_container_engines.push_back(cri_engine); m_container_engines.push_back(cri_engine);
m_container_engine_by_type[CT_CRI].push_back(cri_engine); m_container_engine_by_type[CT_CRI].push_back(cri_engine);
m_container_engine_by_type[CT_CRIO].push_back(cri_engine); m_container_engine_by_type[CT_CRIO].push_back(cri_engine);
m_container_engine_by_type[CT_CONTAINERD].push_back(cri_engine);
engine_index++; engine_index++;
} }
} }
@ -617,7 +619,8 @@ void sinsp_container_manager::create_engines() {
m_container_engine_by_type[CT_BPM].push_back(bpm_engine); m_container_engine_by_type[CT_BPM].push_back(bpm_engine);
} }
if(m_container_engine_mask & (1 << CT_CONTAINERD)) { if(m_container_engine_mask & (1 << CT_CONTAINERD)) {
auto containerd_engine = std::make_shared<container_engine::containerd>(*this); auto containerd_engine =
std::make_shared<container_engine::containerd>(*this, engine_index);
m_container_engines.push_back(containerd_engine); m_container_engines.push_back(containerd_engine);
m_container_engine_by_type[CT_CONTAINERD].push_back(containerd_engine); m_container_engine_by_type[CT_CONTAINERD].push_back(containerd_engine);
} }

View File

@ -37,7 +37,7 @@ constexpr const std::string_view CONTAINERD_SOCKETS[] = {
}; };
bool containerd_async_source::is_ok() { bool containerd_async_source::is_ok() {
return m_container_stub != nullptr && m_image_stub != nullptr; return m_container_stub && m_image_stub;
} }
static inline void setup_grpc_client_context(grpc::ClientContext &context) { static inline void setup_grpc_client_context(grpc::ClientContext &context) {
@ -144,8 +144,11 @@ grpc::Status containerd_async_source::get_image_resp(
return m_image_stub->Get(&context, req, &resp); return m_image_stub->Get(&context, req, &resp);
} }
libsinsp::container_engine::containerd::containerd(container_cache_interface &cache): libsinsp::container_engine::containerd::containerd(container_cache_interface &cache,
size_t engine_index):
container_engine_base(cache) { container_engine_base(cache) {
m_engine_index = engine_index;
for(const auto &p : CONTAINERD_SOCKETS) { for(const auto &p : CONTAINERD_SOCKETS) {
if(p.empty()) { if(p.empty()) {
continue; continue;
@ -158,11 +161,8 @@ libsinsp::container_engine::containerd::containerd(container_cache_interface &ca
} }
container_cache_interface *cache_interface = &container_cache(); container_cache_interface *cache_interface = &container_cache();
auto src = new containerd_async_source(socket_path, m_containerd_info_source =
containerd_async_source::NO_WAIT_LOOKUP, std::make_unique<containerd_async_source>(socket_path, 0, 10000, cache_interface);
10000,
cache_interface);
m_containerd_info_source.reset(src);
if(!m_containerd_info_source->is_ok()) { if(!m_containerd_info_source->is_ok()) {
m_containerd_info_source.reset(nullptr); m_containerd_info_source.reset(nullptr);
continue; continue;
@ -172,6 +172,10 @@ libsinsp::container_engine::containerd::containerd(container_cache_interface &ca
bool containerd_async_source::parse(const containerd_lookup_request &request, bool containerd_async_source::parse(const containerd_lookup_request &request,
sinsp_container_info &container) { sinsp_container_info &container) {
if(!is_ok()) {
return false;
}
auto container_id = request.container_id; auto container_id = request.container_id;
libsinsp_logger()->format(sinsp_logger::SEV_DEBUG, libsinsp_logger()->format(sinsp_logger::SEV_DEBUG,
@ -294,12 +298,13 @@ void libsinsp::container_engine::containerd::parse_containerd(
libsinsp_logger()->format(sinsp_logger::SEV_DEBUG, libsinsp_logger()->format(sinsp_logger::SEV_DEBUG,
"containerd_async (%s): Starting asynchronous lookup", "containerd_async (%s): Starting asynchronous lookup",
request.container_id.c_str()); request.container_id.c_str());
done = m_containerd_info_source->lookup(request, result); done = m_containerd_info_source && m_containerd_info_source->lookup(request, result);
} else { } else {
libsinsp_logger()->format(sinsp_logger::SEV_DEBUG, libsinsp_logger()->format(sinsp_logger::SEV_DEBUG,
"containerd_async (%s): Starting synchronous lookup", "containerd_async (%s): Starting synchronous lookup",
request.container_id.c_str()); request.container_id.c_str());
done = m_containerd_info_source->lookup_sync(request, result);
done = m_containerd_info_source && m_containerd_info_source->lookup_sync(request, result);
} }
if(done) { if(done) {
// if a previous lookup call already found the metadata, process it now // if a previous lookup call already found the metadata, process it now
@ -339,7 +344,7 @@ bool libsinsp::container_engine::containerd::resolve(sinsp_threadinfo *tinfo,
return true; return true;
} }
if(cache->should_lookup(request.container_id, request.container_type)) { if(cache->should_lookup(request.container_id, request.container_type, m_engine_index)) {
libsinsp_logger()->format(sinsp_logger::SEV_DEBUG, libsinsp_logger()->format(sinsp_logger::SEV_DEBUG,
"containerd_async (%s): No existing container info", "containerd_async (%s): No existing container info",
request.container_id.c_str()); request.container_id.c_str());
@ -348,7 +353,7 @@ bool libsinsp::container_engine::containerd::resolve(sinsp_threadinfo *tinfo,
cache->set_lookup_status(request.container_id, cache->set_lookup_status(request.container_id,
request.container_type, request.container_type,
sinsp_container_lookup::state::STARTED, sinsp_container_lookup::state::STARTED,
0); m_engine_index);
parse_containerd(request, cache); parse_containerd(request, cache);
} }
return false; return false;
@ -375,7 +380,7 @@ bool libsinsp::container_engine::containerd::resolve(sinsp_threadinfo *tinfo,
container.m_cpu_period = limits.m_cpu_period; container.m_cpu_period = limits.m_cpu_period;
container.m_cpuset_cpu_count = limits.m_cpuset_cpu_count; container.m_cpuset_cpu_count = limits.m_cpuset_cpu_count;
if(container_cache().should_lookup(container.m_id, CT_CONTAINERD)) { if(container_cache().should_lookup(container.m_id, CT_CONTAINERD, m_engine_index)) {
container.m_name = container.m_id; container.m_name = container.m_id;
container.set_lookup_status(sinsp_container_lookup::state::SUCCESSFUL); container.set_lookup_status(sinsp_container_lookup::state::SUCCESSFUL);
container_cache().add_container(std::make_shared<sinsp_container_info>(container), tinfo); container_cache().add_container(std::make_shared<sinsp_container_info>(container), tinfo);

View File

@ -100,7 +100,7 @@ private:
class containerd : public container_engine_base { class containerd : public container_engine_base {
public: public:
containerd(container_cache_interface& cache); containerd(container_cache_interface& cache, size_t engine_index);
void parse_containerd(const containerd_lookup_request& request, void parse_containerd(const containerd_lookup_request& request,
container_cache_interface* cache); container_cache_interface* cache);
@ -108,6 +108,7 @@ public:
private: private:
std::unique_ptr<containerd_async_source> m_containerd_info_source; std::unique_ptr<containerd_async_source> m_containerd_info_source;
size_t m_engine_index;
}; };
} // namespace container_engine } // namespace container_engine

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
/* /*
Copyright (C) 2023 The Falco Authors. Copyright (C) 2025 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -64,10 +64,15 @@ class RE2;
// UnaryOperator ::= 'exists' // UnaryOperator ::= 'exists'
// NumOperator ::= '<=' | '<' | '>=' | '>' // NumOperator ::= '<=' | '<' | '>=' | '>'
// StrOperator ::= '==' | '=' | '!=' // StrOperator ::= '==' | '=' | '!='
// | 'glob ' | 'iglob ' // | 'bcontains ' | 'bstartswith '
// | 'contains ' | 'icontains ' | 'bcontains ' // | 'contains '
// | 'startswith ' | 'bstartswith ' | 'endswith ' // | 'endswith '
// ListOperator ::= 'intersects' | 'in' | 'pmatch' // | 'glob '
// | 'icontains '
// | 'iglob '
// | 'startswith '
// | 'regex '
// ListOperator ::= 'in' | 'intersects' | 'pmatch'
// FieldTransformerVal ::= 'val(' // FieldTransformerVal ::= 'val('
// FieldTransformerType ::= 'tolower(' | 'toupper(' | 'b64(' | 'basename(' | 'len(' // FieldTransformerType ::= 'tolower(' | 'toupper(' | 'b64(' | 'basename(' | 'len('
// //

View File

@ -27,6 +27,7 @@ namespace {
const size_t CONTAINER_ID_LENGTH = 64; const size_t CONTAINER_ID_LENGTH = 64;
const size_t REPORTED_CONTAINER_ID_LENGTH = 12; const size_t REPORTED_CONTAINER_ID_LENGTH = 12;
const char *CONTAINER_ID_VALID_CHARACTERS = "0123456789abcdefABCDEF";
static_assert(REPORTED_CONTAINER_ID_LENGTH <= CONTAINER_ID_LENGTH, static_assert(REPORTED_CONTAINER_ID_LENGTH <= CONTAINER_ID_LENGTH,
"Reported container ID length cannot be longer than actual length"); "Reported container ID length cannot be longer than actual length");
@ -40,21 +41,6 @@ inline static bool endswith(const std::string &s, const std::string &suffix) {
return s.rfind(suffix) == (s.size() - suffix.size()); return s.rfind(suffix) == (s.size() - suffix.size());
} }
inline static bool is_host(const std::string &cgroup) {
// A good approximation to minize false-positives is to exclude systemd suffixes.
if(endswith(cgroup, ".slice") || endswith(cgroup, ".service")) {
return true;
} else if(endswith(cgroup, ".scope")) {
if(cgroup.find("crio-") != std::string::npos ||
cgroup.find("docker-") != std::string::npos) {
return false;
}
return true;
}
return false;
}
// check if cgroup ends with <prefix><container_id><suffix> // check if cgroup ends with <prefix><container_id><suffix>
// If true, set <container_id> to a truncated version of the id and return true. // If true, set <container_id> to a truncated version of the id and return true.
// Otherwise return false and leave container_id unchanged // Otherwise return false and leave container_id unchanged
@ -73,6 +59,12 @@ bool match_one_container_id(const std::string &cgroup,
return false; return false;
} }
if(end_pos - start_pos == CONTAINER_ID_LENGTH &&
cgroup.find_first_not_of(CONTAINER_ID_VALID_CHARACTERS, start_pos) >= CONTAINER_ID_LENGTH) {
container_id = cgroup.substr(start_pos, REPORTED_CONTAINER_ID_LENGTH);
return true;
}
// In some container runtimes the container the container id is not // In some container runtimes the container the container id is not
// necessarly CONTAINER_ID_LENGTH long and can be arbitrarly defined. // necessarly CONTAINER_ID_LENGTH long and can be arbitrarly defined.
// To keep it simple we only discard the container id > of CONTAINER_ID_LENGTH. // To keep it simple we only discard the container id > of CONTAINER_ID_LENGTH.
@ -80,15 +72,17 @@ bool match_one_container_id(const std::string &cgroup,
return false; return false;
} }
if(is_host(cgroup)) { // Avoid system host cgroups.
return false; if(cgroup.rfind("/default/") == 0 && !endswith(cgroup, ".service") &&
} !endswith(cgroup, ".slice")) {
size_t reported_len = end_pos - start_pos >= REPORTED_CONTAINER_ID_LENGTH size_t reported_len = end_pos - start_pos >= REPORTED_CONTAINER_ID_LENGTH
? REPORTED_CONTAINER_ID_LENGTH ? REPORTED_CONTAINER_ID_LENGTH
: end_pos; : end_pos - start_pos;
container_id = cgroup.substr(start_pos, reported_len); container_id = cgroup.substr(start_pos, reported_len);
return true; return true;
}
return false;
} }
bool match_container_id(const std::string &cgroup, bool match_container_id(const std::string &cgroup,

View File

@ -35,9 +35,10 @@ TEST_F(sinsp_with_test_input, default_cri_socket_paths) {
auto socket_paths = cri_settings.get_cri_unix_socket_paths(); auto socket_paths = cri_settings.get_cri_unix_socket_paths();
ASSERT_EQ(socket_paths.size(), 3); ASSERT_EQ(socket_paths.size(), 4);
ASSERT_TRUE("/run/containerd/containerd.sock" == socket_paths[0]); ASSERT_TRUE("/run/containerd/containerd.sock" == socket_paths[0]);
ASSERT_TRUE("/run/crio/crio.sock" == socket_paths[1]); ASSERT_TRUE("/run/crio/crio.sock" == socket_paths[1]);
ASSERT_TRUE("/run/k3s/containerd/containerd.sock" == socket_paths[2]); ASSERT_TRUE("/run/k3s/containerd/containerd.sock" == socket_paths[2]);
ASSERT_TRUE("/run/host-containerd/containerd.sock" == socket_paths[3]);
} }
#endif #endif