11use crate :: common:: config:: { DEBUG_LOGGING_CONFIG , update_config, write_agent_local_config} ;
2+ use crate :: common:: file:: write;
23use crate :: common:: on_drop:: CleanUp ;
4+ use crate :: common:: test:: { TestResult , retry_panic} ;
35use crate :: common:: { InstallationArgs , RecipeData } ;
4- use crate :: {
5- linux:: {
6- self ,
7- install:: { install_agent_control_from_recipe, tear_down_test} ,
8- bash:: exec_bash_command
9- } ,
6+ use crate :: linux:: {
7+ self ,
8+ bash:: exec_bash_command,
9+ install:: { install_agent_control_from_recipe, tear_down_test} ,
1010} ;
11+ use glob:: glob;
12+ use std:: time:: Duration ;
1113use tracing:: { debug, info} ;
1214
15+ /// Directory where Agent Control loads dynamic (custom) agent type definitions.
16+ const DYNAMIC_AGENT_TYPES_DIR : & str = "/etc/newrelic-agent-control/dynamic-agent-types" ;
17+
18+ /// Expected package installation directory for the preload agent.
19+ fn preload_package_dir ( ) -> String {
20+ format ! (
21+ "{}/packages/nr-preload/stored_packages/preload-agent" ,
22+ linux:: AGENT_CONTROL_DATA_DIR
23+ )
24+ }
25+
1326pub fn test_installation_with_preload_agent ( args : InstallationArgs ) {
1427 let preload_version = args
1528 . preload_version
1629 . clone ( )
17- . expect ( "--preload-agent-version is required for this scenario" ) ;
18-
19- let staging = matches ! ( args. nr_region. to_lowercase( ) . as_str( ) , "staging" ) ;
30+ . expect ( "--preload-version is required for this scenario" ) ;
2031
2132 let recipe_data = RecipeData {
2233 args,
@@ -35,6 +46,40 @@ pub fn test_installation_with_preload_agent(args: InstallationArgs) {
3546
3647 let preload_agent_id = "nr-preload" ;
3748
49+ info ! ( "Writing custom preload agent type definition" ) ;
50+ let custom_agent_type_path = format ! ( "{DYNAMIC_AGENT_TYPES_DIR}/preload.yaml" ) ;
51+ let custom_agent_type = r#"namespace: newrelic
52+ name: com.newrelic.preload
53+ version: 0.1.0
54+ variables:
55+ linux:
56+ oci:
57+ repository:
58+ description: "Package repository name"
59+ type: string
60+ required: false
61+ default: newrelic/preload-agent-artifacts
62+ variants:
63+ ac_config_field: "oci_repository_urls"
64+ values: ["newrelic/preload-agent-artifacts"]
65+ version:
66+ description: "Agent version"
67+ type: string
68+ required: true
69+ deployment:
70+ linux:
71+ packages:
72+ preload-agent:
73+ download:
74+ oci:
75+ repository: ${nr-var:oci.repository}
76+ version: ${nr-var:version}
77+ public_key_url: https://publickeys.newrelic.com/g/agent-control-oci/global/nrpreloadagent/jwks.json
78+ "# ;
79+ exec_bash_command ( & format ! ( "mkdir -p {DYNAMIC_AGENT_TYPES_DIR}" ) )
80+ . unwrap_or_else ( |err| panic ! ( "Failed to create dynamic agent types directory: {err}" ) ) ;
81+ write ( & custom_agent_type_path, custom_agent_type) ;
82+
3883 info ! ( "Setup Agent Control config" ) ;
3984 update_config (
4085 linux:: DEFAULT_AC_CONFIG_PATH ,
@@ -51,35 +96,48 @@ agents:
5196
5297 write_agent_local_config (
5398 & linux:: local_config_path ( preload_agent_id) ,
54- // Correct Config?
5599 format ! { r#"
56- fleet_id: alphanumeric_id # needed anymore?
57- apm_language: java
58- agent_version: 8.13.0
59- application_names:
60- - my-app
61- - functions
62- - lib
63- - bin
64- new_relic_license_key: '{{{{NEW_RELIC_LICENSE_KEY}}}}'
65- staging: {staging}
66- version: {preload_version}"# } ,
100+ version: {preload_version}"# } ,
67101 ) ;
68102
103+ linux:: service:: restart_service ( linux:: SERVICE_NAME ) ;
69104
70- // ToDo update with actual path
71- let ld_preload_path = "path_to_ld_preload" ;
72- let install_command = format ! ( r#"echo "{ld_preload_path}" >> /ec/ld.so.preload"# ) ;
73- let output = exec_bash_command ( & install_command)
74- . unwrap_or_else ( |err| panic ! ( "Editing /ec/ld.so.preload failed: {err}" ) ) ;
75- debug ! ( "echo output:\n {output}" ) ;
105+ info ! ( "Waiting for preload OCI package to be downloaded and extracted" ) ;
106+ let package_dir = preload_package_dir ( ) ;
107+ let retries = 60 ;
108+ retry_panic (
109+ retries,
110+ Duration :: from_secs ( 10 ) ,
111+ "preload package download assertion" ,
112+ || assert_preload_package_downloaded ( & package_dir) ,
113+ ) ;
76114
77- linux:: service:: restart_service ( linux:: SERVICE_NAME ) ;
115+ info ! ( "Searching for shared library inside extracted package" ) ;
116+ let so_path = glob ( & format ! ( "{package_dir}/**/*.so" ) )
117+ . expect ( "Failed to read glob pattern" )
118+ . find_map ( |entry| entry. ok ( ) )
119+ . map ( |path| path. to_string_lossy ( ) . into_owned ( ) )
120+ . unwrap_or_default ( ) ;
121+ if so_path. is_empty ( ) {
122+ panic ! ( "No .so file found in extracted preload package at {package_dir}" ) ;
123+ }
124+ info ! ( "Found shared library: {so_path}" ) ;
78125
79- let ls_command = format ! ( "ls {ld_preload_path}" ) ;
80- let output = exec_bash_command ( & ls_command)
81- . unwrap_or_else ( |err| panic ! ( "Installation failed: {err}" ) ) ;
82- debug ! ( "ls output:\n {output}" ) ;
126+ info ! ( "Installing shared library into /etc/ld.so.preload" ) ;
127+ let install_command = format ! ( r#"echo "{so_path}" >> /etc/ld.so.preload"# ) ;
128+ let output = exec_bash_command ( & install_command)
129+ . unwrap_or_else ( |err| panic ! ( "Editing /etc/ld.so.preload failed: {err}" ) ) ;
130+ debug ! ( "Install output:\n {output}" ) ;
83131
84132 info ! ( "Test completed successfully" ) ;
85133}
134+
135+ fn assert_preload_package_downloaded ( package_dir : & str ) -> TestResult < ( ) > {
136+ let output = exec_bash_command ( & format ! ( "ls -d {package_dir}" ) ) ?;
137+ if output. contains ( "No such file" ) || output. contains ( "cannot access" ) {
138+ return Err ( format ! ( "Preload package directory not found yet at {package_dir}" ) . into ( ) ) ;
139+ }
140+ let listing = exec_bash_command ( & format ! ( "ls -la {package_dir}" ) ) ?;
141+ debug ! ( "Package listing:\n {listing}" ) ;
142+ Ok ( ( ) )
143+ }
0 commit comments