@@ -76,8 +76,8 @@ use crate::repository::{
7676} ;
7777use crate :: types:: {
7878 BmcPasswordProvider , ConfigPortsServiceType , DHCP_SERVER_SERVICE_NAME , DOCA_HBN_SERVICE_NAME ,
79- DPU_AGENT_SERVICE_NAME , DpuDeviceInfo , DpuDeviceSummary , DpuMismatch , DpuNodeInfo ,
80- DpuNodeSummary , DpuPhase , DpuServiceInterfaceTemplateDefinition ,
79+ DPU_AGENT_SERVICE_NAME , DTS_SERVICE_NAME , DpuDeviceInfo , DpuDeviceSummary , DpuMismatch ,
80+ DpuNodeInfo , DpuNodeSummary , DpuPhase , DpuServiceInterfaceTemplateDefinition ,
8181 DpuServiceInterfaceTemplateType , DpuSummary , FMDS_SERVICE_NAME , HostDpfSnapshot ,
8282 InitDpfResourcesConfig , OTEL_COLLECTOR_SERVICE_NAME , ServiceConfigPortProtocol ,
8383 ServiceDefinition , ServiceNADResourceType , ServiceTemplateVersion ,
@@ -665,6 +665,12 @@ pub fn build_deployment<L: ResourceLabeler>(
665665 DpuDeploymentServicesDependsOn {
666666 name: FMDS_SERVICE_NAME . to_string( ) ,
667667 } ,
668+ // otelcol templates the DTS scrape target from
669+ // `{{ (index .Services "dts").Name }}`; without this
670+ // dependency that lookup renders empty.
671+ DpuDeploymentServicesDependsOn {
672+ name: DTS_SERVICE_NAME . to_string( ) ,
673+ } ,
668674 ] ) ,
669675
670676 _ => None ,
@@ -1829,6 +1835,53 @@ mod tests {
18291835
18301836 const TEST_NAMESPACE : & str = "test-namespace" ;
18311837
1838+ #[ test]
1839+ fn otelcol_depends_on_includes_dts ( ) {
1840+ // Regression: otelcol templates its DTS scrape target from
1841+ // `{{ (index .Services "dts").Name }}`. That lookup only resolves when
1842+ // dts is declared as a dependency of the otelcol service, otherwise the
1843+ // rendered target host is `carbide-dpf-cluster--doca-telemetry` (empty
1844+ // name) and DTS metrics never get scraped.
1845+ let svc = |name : & str | ServiceDefinition :: new ( name, "repo" , "chart" , "1.0.0" ) ;
1846+ let services = vec ! [
1847+ svc( OTEL_COLLECTOR_SERVICE_NAME ) ,
1848+ svc( DTS_SERVICE_NAME ) ,
1849+ svc( DPU_AGENT_SERVICE_NAME ) ,
1850+ svc( FMDS_SERVICE_NAME ) ,
1851+ ] ;
1852+
1853+ let deployment = build_deployment (
1854+ & services,
1855+ "dep" ,
1856+ "bfb" ,
1857+ "flavor" ,
1858+ TEST_NAMESPACE ,
1859+ & NoLabels ,
1860+ & [ ] ,
1861+ ) ;
1862+
1863+ let otel = deployment
1864+ . spec
1865+ . services
1866+ . get ( OTEL_COLLECTOR_SERVICE_NAME )
1867+ . expect ( "otelcol service present" ) ;
1868+ let deps: Vec < String > = otel
1869+ . depends_on
1870+ . as_ref ( )
1871+ . expect ( "otelcol should declare dependencies" )
1872+ . iter ( )
1873+ . map ( |d| d. name . clone ( ) )
1874+ . collect ( ) ;
1875+
1876+ assert ! (
1877+ deps. contains( & DTS_SERVICE_NAME . to_string( ) ) ,
1878+ "otelcol must depend on dts so its scrape target resolves; got {deps:?}"
1879+ ) ;
1880+ // The previously-working dependencies must remain.
1881+ assert ! ( deps. contains( & DPU_AGENT_SERVICE_NAME . to_string( ) ) ) ;
1882+ assert ! ( deps. contains( & FMDS_SERVICE_NAME . to_string( ) ) ) ;
1883+ }
1884+
18321885 #[ derive( Clone , Default ) ]
18331886 struct SdkMock {
18341887 devices : Arc < RwLock < BTreeMap < String , DPUDevice > > > ,
0 commit comments