Skip to content

Commit bebd7a4

Browse files
Kyle-Nealeclaude
andcommitted
feat(base): add get_agent_embedded_path helper
Resolve paths under the agent's `embedded` directory by reading `run_path` from the agent config instead of assuming the install sits at `/opt/datadog-agent`. Works for both standard installs and Remote-Management installs at `/opt/datadog-packages/datadog-agent/<ver>`. Returns `None` when `run_path` is unset so callers can decide whether the miss is fatal (raise) or skip a fallback. Refs: AI-5681 Follow-up to #20574 which inlined this lookup in glusterfs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 1722e6a commit bebd7a4

3 files changed

Lines changed: 72 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add `get_agent_embedded_path` helper to resolve paths under the agent's embedded directory regardless of install location.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,27 @@
11
# (C) Datadog, Inc. 2019-present
22
# All rights reserved
33
# Licensed under a 3-clause BSD style license (see LICENSE)
4+
import os
5+
6+
try:
7+
import datadog_agent
8+
except ImportError:
9+
from datadog_checks.base.stubs import datadog_agent
10+
411
METRIC_NAMESPACE_METRICS = 'datadog.agent.metrics'
512
METRIC_NAMESPACE_PROFILE = 'datadog.agent.profile'
13+
14+
15+
def get_agent_embedded_path(*parts: str) -> str | None:
16+
"""Resolve a path under the agent's `embedded` directory from the agent's `run_path` config.
17+
18+
Returns ``None`` when ``run_path`` is unset so callers can decide whether the
19+
miss is fatal or merely skips a fallback. Works for both the standard install
20+
(``/opt/datadog-agent/run``) and Remote-Management installs
21+
(``/opt/datadog-packages/datadog-agent/<version>/run``).
22+
"""
23+
run_path = datadog_agent.get_config('run_path')
24+
if not run_path:
25+
return None
26+
install_path = run_path[:-4] if run_path.endswith('/run') else run_path
27+
return os.path.join(install_path, 'embedded', *parts)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# (C) Datadog, Inc. 2026-present
2+
# All rights reserved
3+
# Licensed under a 3-clause BSD style license (see LICENSE)
4+
import mock
5+
6+
from datadog_checks.base.utils.agent.common import get_agent_embedded_path
7+
8+
9+
class TestGetAgentEmbeddedPath:
10+
def test_standard_install(self):
11+
with mock.patch(
12+
'datadog_checks.base.utils.agent.common.datadog_agent.get_config',
13+
return_value='/opt/datadog-agent/run',
14+
):
15+
assert get_agent_embedded_path('sbin', 'gstatus') == '/opt/datadog-agent/embedded/sbin/gstatus'
16+
17+
def test_remote_management_install(self):
18+
with mock.patch(
19+
'datadog_checks.base.utils.agent.common.datadog_agent.get_config',
20+
return_value='/opt/datadog-packages/datadog-agent/7.79.0/run',
21+
):
22+
assert (
23+
get_agent_embedded_path('sbin', 'gstatus')
24+
== '/opt/datadog-packages/datadog-agent/7.79.0/embedded/sbin/gstatus'
25+
)
26+
27+
def test_missing_run_path_returns_none(self):
28+
with mock.patch(
29+
'datadog_checks.base.utils.agent.common.datadog_agent.get_config',
30+
return_value='',
31+
):
32+
assert get_agent_embedded_path('sbin', 'gstatus') is None
33+
34+
def test_run_path_without_trailing_run(self):
35+
with mock.patch(
36+
'datadog_checks.base.utils.agent.common.datadog_agent.get_config',
37+
return_value='/custom/agent/dir',
38+
):
39+
assert (
40+
get_agent_embedded_path('ssl', 'certs', 'cacert.pem')
41+
== '/custom/agent/dir/embedded/ssl/certs/cacert.pem'
42+
)
43+
44+
def test_no_parts_returns_embedded_dir(self):
45+
with mock.patch(
46+
'datadog_checks.base.utils.agent.common.datadog_agent.get_config',
47+
return_value='/opt/datadog-agent/run',
48+
):
49+
assert get_agent_embedded_path() == '/opt/datadog-agent/embedded'

0 commit comments

Comments
 (0)