Skip to main content

datadog_agent_config/
platform_default.rs

1//! Runtime selection of a schema `platform_default` value.
2//!
3//! Some schema settings declare a `platform_default` mapping (platform key -> value) instead of a single `default`.
4//! The Agent resolves it when it starts, not when it is built (`getPlatformDefault` in `pkg/config/setup/config.go`):
5//! `fargate` wins when running on ECS Fargate, then `container` when containerized, then the operating system, then
6//! the `other` catch-all. The generated `platform_defaults` functions call [`resolve`] to pick the same key, so the
7//! checked-in generated code stays independent of the host that produced it.
8
9/// Returns the platform key whose value applies to this process, among the keys a setting declares.
10///
11/// Returns `""` when none applies (a mapping with no `other` key on an unlisted platform), in which case the setting
12/// defaults to its type's zero value, as the Agent's `nil` default would.
13pub(crate) fn resolve(platforms_with_defaults: &[&'static str]) -> &'static str {
14    resolve_with(platforms_with_defaults, goos(), is_ecs_fargate(), is_containerized())
15}
16
17fn resolve_with(
18    platforms_with_defaults: &[&'static str], goos: &'static str, ecs_fargate: bool, containerized: bool,
19) -> &'static str {
20    // The keys that could apply to this process, from most to least specific.
21    let candidates = [
22        ecs_fargate.then_some("fargate"),
23        containerized.then_some("container"),
24        Some(goos),
25        Some("other"),
26    ];
27    candidates
28        .into_iter()
29        .flatten()
30        .find(|candidate| platforms_with_defaults.contains(candidate))
31        .unwrap_or("")
32}
33
34/// The operating system under the name Go's `runtime.GOOS` gives it, which is what platform keys use.
35fn goos() -> &'static str {
36    match std::env::consts::OS {
37        "macos" => "darwin",
38        os => os,
39    }
40}
41
42/// Mirrors the Agent's `env.IsECSFargate`.
43fn is_ecs_fargate() -> bool {
44    std::env::var_os("ECS_FARGATE").is_some_and(|value| !value.is_empty())
45        || std::env::var_os("AWS_EXECUTION_ENV").is_some_and(|value| value == "AWS_ECS_FARGATE")
46}
47
48/// Returns `true` if this process runs in the Datadog Agent's container image.
49///
50/// Mirrors the Agent's `env.IsContainerized`, which checks for the `DOCKER_DD_AGENT` environment variable that the
51/// image sets.
52pub fn is_containerized() -> bool {
53    std::env::var_os("DOCKER_DD_AGENT").is_some_and(|value| !value.is_empty())
54}
55
56#[cfg(test)]
57mod tests {
58    use super::resolve_with;
59
60    const ALL: &[&str] = &["aix", "container", "darwin", "fargate", "linux", "other", "windows"];
61
62    #[test]
63    fn the_operating_system_is_chosen_when_listed() {
64        assert_eq!(resolve_with(ALL, "linux", false, false), "linux");
65        assert_eq!(resolve_with(ALL, "darwin", false, false), "darwin");
66    }
67
68    #[test]
69    fn fargate_takes_precedence_over_container_and_the_operating_system() {
70        assert_eq!(resolve_with(ALL, "linux", true, true), "fargate");
71    }
72
73    #[test]
74    fn container_takes_precedence_over_the_operating_system() {
75        assert_eq!(resolve_with(ALL, "linux", false, true), "container");
76    }
77
78    #[test]
79    fn a_runtime_key_applies_only_when_declared() {
80        assert_eq!(resolve_with(&["linux", "other"], "linux", true, true), "linux");
81    }
82
83    #[test]
84    fn an_unlisted_operating_system_falls_back_to_other() {
85        assert_eq!(resolve_with(&["linux", "other"], "windows", false, false), "other");
86    }
87
88    #[test]
89    fn no_key_applies_without_other() {
90        assert_eq!(resolve_with(&["linux", "windows"], "freebsd", false, false), "");
91    }
92
93    #[test]
94    fn the_host_operating_system_uses_go_naming() {
95        assert_ne!(super::goos(), "macos");
96    }
97}