-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathpreload_agent.rs
More file actions
141 lines (124 loc) · 4.69 KB
/
Copy pathpreload_agent.rs
File metadata and controls
141 lines (124 loc) · 4.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use crate::common::config::{DEBUG_LOGGING_CONFIG, update_config, write_agent_local_config};
use crate::common::file::write;
use crate::common::on_drop::CleanUp;
use crate::common::test::{TestResult, retry_panic};
use crate::common::{InstallationArgs, RecipeData};
use crate::linux::{
self,
bash::exec_bash_command,
install::{install_agent_control_from_recipe, tear_down_test},
};
use std::time::Duration;
use tracing::{debug, info};
/// Directory where Agent Control loads dynamic (custom) agent type definitions.
const DYNAMIC_AGENT_TYPES_DIR: &str = "/etc/newrelic-agent-control/dynamic-agent-types";
/// Expected package installation directory for the preload agent.
fn preload_package_dir() -> String {
format!(
"{}/packages/nr-preload/stored_packages/preload-agent",
linux::AGENT_CONTROL_DATA_DIR
)
}
pub fn test_installation_with_preload_agent(args: InstallationArgs) {
let preload_version = args
.preload_version
.clone()
.expect("--preload-version is required for this scenario");
let recipe_data = RecipeData {
args,
monitoring_source: "preload-agent".to_string(),
..Default::default()
};
let _clean_up = CleanUp::new(tear_down_test);
install_agent_control_from_recipe(&recipe_data);
let test_id = format!(
"onhost-e2e-preload-agent_{}",
chrono::Local::now().format("%Y-%m-%d_%H-%M-%S%.3f")
);
let preload_agent_id = "nr-preload";
info!("Writing custom preload agent type definition");
let custom_agent_type_path = format!("{DYNAMIC_AGENT_TYPES_DIR}/preload.yaml");
let custom_agent_type = r#"namespace: newrelic
name: com.newrelic.preload
version: 0.1.0
variables:
linux:
oci:
repository:
description: "Package repository name"
type: string
required: false
default: newrelic/preload-agent-artifacts
variants:
ac_config_field: "oci_repository_urls"
values: ["newrelic/preload-agent-artifacts"]
version:
description: "Agent version"
type: string
required: true
deployment:
linux:
packages:
preload-agent:
download:
oci:
repository: ${{nr-var:oci.repository}}
version: ${{nr-var:version}}
public_key_url: https://publickeys.newrelic.com/g/agent-control-oci/global/nrpreloadagent/jwks.json
"#;
exec_bash_command(&format!("mkdir -p {DYNAMIC_AGENT_TYPES_DIR}"))
.unwrap_or_else(|err| panic!("Failed to create dynamic agent types directory: {err}"));
write(&custom_agent_type_path, custom_agent_type);
info!("Setup Agent Control config");
update_config(
linux::DEFAULT_AC_CONFIG_PATH,
format!(
r#"
host_id: {test_id}
agents:
nr-preload:
agent_type: "newrelic/com.newrelic.preload:0.1.0"
{DEBUG_LOGGING_CONFIG}
"#
),
);
write_agent_local_config(
&linux::local_config_path(preload_agent_id),
format! {r#"
version: {preload_version}"#},
);
linux::service::restart_service(linux::SERVICE_NAME);
info!("Waiting for preload OCI package to be downloaded and extracted");
let package_dir = preload_package_dir();
let retries = 60;
retry_panic(
retries,
Duration::from_secs(10),
"preload package download assertion",
|| assert_preload_package_downloaded(&package_dir),
);
info!("Searching for shared library inside extracted package");
let find_so_command = format!(r#"find {package_dir} -type f -name "*.so" | head -n 1"#);
let so_path = exec_bash_command(&find_so_command)
.unwrap_or_else(|err| panic!("Failed to find shared library in package: {err}"));
let so_path = so_path.lines().last().unwrap_or("").trim().to_string();
if so_path.is_empty() {
panic!("No .so file found in extracted preload package at {package_dir}");
}
info!("Found shared library: {so_path}");
info!("Installing shared library into /etc/ld.so.preload");
let install_command = format!(r#"echo "{so_path}" >> /etc/ld.so.preload"#);
let output = exec_bash_command(&install_command)
.unwrap_or_else(|err| panic!("Editing /etc/ld.so.preload failed: {err}"));
debug!("Install output:\n{output}");
info!("Test completed successfully");
}
fn assert_preload_package_downloaded(package_dir: &str) -> TestResult<()> {
let output = exec_bash_command(&format!("ls -d {package_dir}"))?;
if output.contains("No such file") || output.contains("cannot access") {
return Err(format!("Preload package directory not found yet at {package_dir}").into());
}
let listing = exec_bash_command(&format!("ls -la {package_dir}"))?;
debug!("Package listing:\n{listing}");
Ok(())
}