-
Notifications
You must be signed in to change notification settings - Fork 280
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Telemetry] Detect if vcpkg is running in a container (#730)
* [wip] Implement Windows Container heuristics * Add Linux containers heuristics * Use GetUserNameW() on Windows * Add detected container metric * Reorder metrics * Test cgroup parser * Apply suggestions from code review Co-authored-by: Billy O'Neal <[email protected]> * Update src/vcpkg.cpp * Fix osx build by removing unnecessary std::moves. Co-authored-by: Billy O'Neal <[email protected]>
- Loading branch information
1 parent
d775ad2
commit b586c27
Showing
9 changed files
with
234 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,3 +22,4 @@ node_modules/ | |
/ce/test/vcpkg-ce.test.build.log | ||
/ce/common/temp | ||
/vcpkg-root | ||
/CMakePresets.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#pragma once | ||
|
||
#include <vcpkg/base/fwd/stringview.h> | ||
|
||
#include <string> | ||
|
||
namespace vcpkg | ||
{ | ||
struct ControlGroup | ||
{ | ||
long hierarchy_id; | ||
std::string subsystems; | ||
std::string control_group; | ||
|
||
ControlGroup(long id, StringView s, StringView c); | ||
}; | ||
|
||
std::vector<ControlGroup> parse_cgroup_file(StringView text, StringView origin); | ||
|
||
bool detect_docker_in_cgroup_file(StringView text, StringView origin); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
#include <catch2/catch.hpp> | ||
|
||
#include <vcpkg/base/stringview.h> | ||
|
||
#include <vcpkg/cgroup-parser.h> | ||
|
||
using namespace vcpkg; | ||
|
||
TEST_CASE ("parse", "[cgroup-parser]") | ||
{ | ||
auto ok_text = R"( | ||
3:cpu:/ | ||
2:cpuset:/ | ||
1:memory:/ | ||
0::/ | ||
)"; | ||
|
||
auto cgroups = parse_cgroup_file(ok_text, "ok_text"); | ||
REQUIRE(cgroups.size() == 4); | ||
CHECK(cgroups[0].hierarchy_id == 3); | ||
CHECK(cgroups[0].subsystems == "cpu"); | ||
CHECK(cgroups[0].control_group == "/"); | ||
CHECK(cgroups[1].hierarchy_id == 2); | ||
CHECK(cgroups[1].subsystems == "cpuset"); | ||
CHECK(cgroups[1].control_group == "/"); | ||
CHECK(cgroups[2].hierarchy_id == 1); | ||
CHECK(cgroups[2].subsystems == "memory"); | ||
CHECK(cgroups[2].control_group == "/"); | ||
CHECK(cgroups[3].hierarchy_id == 0); | ||
CHECK(cgroups[3].subsystems == ""); | ||
CHECK(cgroups[3].control_group == "/"); | ||
|
||
auto cgroups_short = parse_cgroup_file("2::", "short_text"); | ||
REQUIRE(cgroups_short.size() == 1); | ||
CHECK(cgroups_short[0].hierarchy_id == 2); | ||
CHECK(cgroups_short[0].subsystems == ""); | ||
CHECK(cgroups_short[0].control_group == ""); | ||
|
||
auto cgroups_incomplete = parse_cgroup_file("0:/", "incomplete_text"); | ||
CHECK(cgroups_incomplete.empty()); | ||
|
||
auto cgroups_bad_id = parse_cgroup_file("ab::", "non_numeric_id_text"); | ||
CHECK(cgroups_bad_id.empty()); | ||
|
||
auto cgroups_empty = parse_cgroup_file("", "empty"); | ||
CHECK(cgroups_empty.empty()); | ||
} | ||
|
||
TEST_CASE ("detect docker", "[cgroup-parser]") | ||
{ | ||
auto with_docker = R"( | ||
2:memory:/docker/66a5f8000f3f2e2a19c3f7d60d870064d26996bdfe77e40df7e3fc955b811d14 | ||
1:name=systemd:/docker/66a5f8000f3f2e2a19c3f7d60d870064d26996bdfe77e40df7e3fc955b811d14 | ||
0::/docker/66a5f8000f3f2e2a19c3f7d60d870064d26996bdfe77e40df7e3fc955b811d14 | ||
)"; | ||
|
||
auto without_docker = R"( | ||
3:cpu:/ | ||
2:cpuset:/ | ||
1:memory:/ | ||
0::/ | ||
)"; | ||
|
||
CHECK(detect_docker_in_cgroup_file(with_docker, "with_docker")); | ||
CHECK(!detect_docker_in_cgroup_file(without_docker, "without_docker")); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#include <vcpkg/base/parse.h> | ||
#include <vcpkg/base/stringview.h> | ||
#include <vcpkg/base/system.debug.h> | ||
#include <vcpkg/base/util.h> | ||
|
||
#include <vcpkg/cgroup-parser.h> | ||
|
||
namespace vcpkg | ||
{ | ||
ControlGroup::ControlGroup(long id, StringView s, StringView c) | ||
: hierarchy_id(id), subsystems(s.data(), s.size()), control_group(c.data(), c.size()) | ||
{ | ||
} | ||
|
||
// parses /proc/[pid]/cgroup file as specified in https://linux.die.net/man/5/proc | ||
// The file describes control groups to which the process/tasks belongs. | ||
// For each cgroup hierarchy there is one entry | ||
// containing colon-separated fields of the form: | ||
// 5:cpuacct,cpu,cpuset:/daemos | ||
// | ||
// The colon separated fields are, from left to right: | ||
// | ||
// 1. hierarchy ID number | ||
// 2. set of subsystems bound to the hierarchy | ||
// 3. control group in the hierarchy to which the process belongs | ||
std::vector<ControlGroup> parse_cgroup_file(StringView text, StringView origin) | ||
{ | ||
using P = ParserBase; | ||
constexpr auto is_separator_or_lineend = [](auto ch) { return ch == ':' || P::is_lineend(ch); }; | ||
|
||
auto parser = ParserBase(text, origin); | ||
parser.skip_whitespace(); | ||
|
||
std::vector<ControlGroup> ret; | ||
while (!parser.at_eof()) | ||
{ | ||
auto id = parser.match_until(is_separator_or_lineend); | ||
auto maybe_numeric_id = Strings::strto<long>(id); | ||
if (!maybe_numeric_id || P::is_lineend(parser.cur())) | ||
{ | ||
ret.clear(); | ||
break; | ||
} | ||
|
||
parser.next(); | ||
auto subsystems = parser.match_until(is_separator_or_lineend); | ||
if (P::is_lineend(parser.cur())) | ||
{ | ||
ret.clear(); | ||
break; | ||
} | ||
|
||
parser.next(); | ||
auto control_group = parser.match_until(P::is_lineend); | ||
parser.skip_whitespace(); | ||
|
||
ret.emplace_back(*maybe_numeric_id.get(), subsystems, control_group); | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
bool detect_docker_in_cgroup_file(StringView text, StringView origin) | ||
{ | ||
return Util::any_of(parse_cgroup_file(text, origin), [](auto&& cgroup) { | ||
return Strings::starts_with(cgroup.control_group, "/docker") || | ||
Strings::starts_with(cgroup.control_group, "/lxc"); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters