Skip to content

Commit 65f8f84

Browse files
authored
chore: simplify agent-control command (#1617)
1 parent 6f5a535 commit 65f8f84

File tree

6 files changed

+70
-125
lines changed

6 files changed

+70
-125
lines changed

agent-control/src/agent_control/run.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ impl AgentControlRunner {
191191

192192
#[cfg(debug_assertions)]
193193
/// Set path override if local_dir, remote_dir, and logs_dir flags are set
194-
pub fn set_debug_dirs(base_paths: BasePaths, cli: &crate::flags::Flags) -> BasePaths {
194+
pub fn set_debug_dirs(base_paths: BasePaths, cli: &crate::command::Command) -> BasePaths {
195195
let mut base_paths = base_paths;
196196

197197
if let Some(ref local_path) = cli.local_dir {

agent-control/src/bin/main_k8s.rs

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
use newrelic_agent_control::agent_control::run::{
88
AgentControlRunConfig, AgentControlRunner, Environment,
99
};
10+
use newrelic_agent_control::command::Command;
1011
use newrelic_agent_control::event::ApplicationEvent;
1112
use newrelic_agent_control::event::channel::{EventPublisher, pub_sub};
12-
use newrelic_agent_control::flags::{Command, Flags};
1313
use newrelic_agent_control::http::tls::install_rustls_default_crypto_provider;
1414
use newrelic_agent_control::instrumentation::tracing::TracingGuardBox;
1515
use std::error::Error;
@@ -19,35 +19,7 @@ use tracing::{error, info, trace};
1919
const AGENT_CONTROL_MODE: Environment = Environment::K8s;
2020

2121
fn main() -> ExitCode {
22-
let Ok(command) = Flags::init(AGENT_CONTROL_MODE)
23-
.inspect_err(|init_err| println!("Error parsing Flags: {init_err}"))
24-
else {
25-
return ExitCode::FAILURE;
26-
};
27-
28-
let (agent_control_config, tracer) = match command {
29-
// Agent Control command call instructs normal operation. Continue with required data.
30-
Command::InitAgentControl(agent_control_init_config, tracer) => {
31-
(agent_control_init_config, tracer)
32-
}
33-
34-
// Agent Control command call was a "one-shot" operation. Exit successfully after performing.
35-
Command::OneShot(op) => {
36-
op.run_one_shot(AGENT_CONTROL_MODE);
37-
return ExitCode::SUCCESS;
38-
}
39-
};
40-
41-
match _main(*agent_control_config, tracer) {
42-
Err(e) => {
43-
error!("The agent control main process exited with an error: {e}");
44-
ExitCode::FAILURE
45-
}
46-
Ok(()) => {
47-
info!("The agent control main process exited successfully");
48-
ExitCode::SUCCESS
49-
}
50-
}
22+
Command::run(AGENT_CONTROL_MODE, _main)
5123
}
5224

5325
/// This is the actual main function.

agent-control/src/bin/main_onhost.rs

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ use newrelic_agent_control::agent_control::pid_cache::PIDCache;
99
use newrelic_agent_control::agent_control::run::{
1010
AgentControlRunConfig, AgentControlRunner, Environment,
1111
};
12+
use newrelic_agent_control::command::Command;
1213
use newrelic_agent_control::event::ApplicationEvent;
1314
use newrelic_agent_control::event::channel::{EventPublisher, pub_sub};
14-
use newrelic_agent_control::flags::{Command, Flags};
1515
use newrelic_agent_control::http::tls::install_rustls_default_crypto_provider;
1616
use newrelic_agent_control::instrumentation::tracing::TracingGuardBox;
1717
use std::error::Error;
@@ -21,35 +21,7 @@ use tracing::{error, info, trace};
2121
const AGENT_CONTROL_MODE: Environment = Environment::OnHost;
2222

2323
fn main() -> ExitCode {
24-
let Ok(command) = Flags::init(AGENT_CONTROL_MODE)
25-
.inspect_err(|init_err| println!("Error parsing Flags: {init_err}"))
26-
else {
27-
return ExitCode::FAILURE;
28-
};
29-
30-
let (agent_control_config, tracer) = match command {
31-
// Agent Control command call instructs normal operation. Continue with required data.
32-
Command::InitAgentControl(agent_control_init_config, tracer) => {
33-
(agent_control_init_config, tracer)
34-
}
35-
36-
// Agent Control command call was a "one-shot" operation. Exit successfully after performing.
37-
Command::OneShot(op) => {
38-
op.run_one_shot(AGENT_CONTROL_MODE);
39-
return ExitCode::SUCCESS;
40-
}
41-
};
42-
43-
match _main(*agent_control_config, tracer) {
44-
Err(e) => {
45-
error!("The agent control main process exited with an error: {e}");
46-
ExitCode::FAILURE
47-
}
48-
Ok(()) => {
49-
info!("The agent control main process exited successfully");
50-
ExitCode::SUCCESS
51-
}
52-
}
24+
Command::run(AGENT_CONTROL_MODE, _main)
5325
}
5426

5527
/// This is the actual main function.
Lines changed: 59 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -19,40 +19,32 @@ use crate::{
1919
utils::binary_metadata::binary_metadata,
2020
};
2121
use clap::Parser;
22+
use std::error::Error;
23+
use std::process::ExitCode;
2224
use std::sync::Arc;
23-
use thiserror::Error;
24-
use tracing::info;
25+
use tracing::{error, info};
2526

2627
/// All possible errors that can happen while running the initialization.
27-
#[derive(Debug, Error)]
28+
#[derive(Debug, thiserror::Error)]
2829
pub enum InitError {
2930
/// Could not initialize tracer
30-
#[error("could not initialize tracer: `{0}`")]
31+
#[error("could not initialize tracer: {0}")]
3132
TracerError(#[from] TracingError),
3233
/// K8s config is missing
33-
#[error("k8s config missing while running on k8s ")]
34+
#[error("k8s config missing while running on k8s")]
3435
K8sConfig(),
3536
/// The config could not be read
36-
#[error("could not read Agent Control config from `{0}`: `{1}`")]
37+
#[error("could not read Agent Control config from {0}: {1}")]
3738
LoaderError(String, String),
3839
/// The configuration is invalid
39-
#[error("invalid configuration: `{0}`")]
40+
#[error("invalid configuration: {0}")]
4041
InvalidConfig(String),
4142
}
4243

43-
/// What action was requested from the initialization?
44-
pub enum Command {
45-
/// Normal operation requested. Get the required config and continue.
46-
InitAgentControl(Box<AgentControlRunConfig>, Vec<TracingGuardBox>),
47-
/// Do a "one-shot" operation and exit successfully.
48-
/// In the future, many different operations could be added here.
49-
OneShot(OneShotCommand),
50-
}
51-
5244
/// Command line arguments for Agent Control, as parsed by [`clap`].
5345
#[derive(Parser, Debug)]
5446
#[command(author, about, long_about = None)] // Read from `Cargo.toml`
55-
pub struct Flags {
47+
pub struct Command {
5648
#[arg(long)]
5749
print_debug_info: bool,
5850

@@ -75,9 +67,22 @@ pub struct Flags {
7567
pub logs_dir: Option<std::path::PathBuf>,
7668
}
7769

78-
impl Flags {
79-
/// Parses command line arguments and decides how the application runs.
80-
pub fn init(mode: Environment) -> Result<Command, InitError> {
70+
impl Command {
71+
/// Checks if the flag to show the version was set
72+
fn print_version(&self) -> bool {
73+
self.version
74+
}
75+
76+
/// Checks if the flag to show debug information was set
77+
fn print_debug_info(&self) -> bool {
78+
self.print_debug_info
79+
}
80+
81+
/// Runs the provided main function or shows the binary information according to flags
82+
pub fn run<F: Fn(AgentControlRunConfig, Vec<TracingGuardBox>) -> Result<(), Box<dyn Error>>>(
83+
mode: Environment,
84+
main_fn: F,
85+
) -> ExitCode {
8186
// Get command line args
8287
let flags = Self::parse();
8388

@@ -87,14 +92,44 @@ impl Flags {
8792
#[cfg(debug_assertions)]
8893
let base_paths = set_debug_dirs(base_paths, &flags);
8994

90-
// If the version flag is set, print the version and exit
95+
// Handle flags requiring different execution mode
9196
if flags.print_version() {
92-
return Ok(Command::OneShot(OneShotCommand::PrintVersion));
97+
println!("{}", binary_metadata(mode));
98+
return ExitCode::SUCCESS;
9399
}
94100
if flags.print_debug_info() {
95-
return Ok(Command::OneShot(OneShotCommand::PrintDebugInfo(flags)));
101+
println!("Printing debug info");
102+
println!("Agent Control Mode: {mode:?}");
103+
println!("FLAGS: {flags:#?}");
104+
return ExitCode::SUCCESS;
105+
}
106+
107+
let Ok((run_config, tracer)) =
108+
Self::init_agent_control(mode, base_paths).inspect_err(|err| {
109+
// Using print because the tracer might have failed to start
110+
println!("Error on Agent Control initialization: {err}");
111+
})
112+
else {
113+
return ExitCode::FAILURE;
114+
};
115+
116+
match main_fn(run_config, tracer) {
117+
Ok(_) => {
118+
info!("The agent control main process exited successfully");
119+
ExitCode::SUCCESS
120+
}
121+
Err(err) => {
122+
error!("The agent control main process exited with an error: {err}");
123+
ExitCode::FAILURE
124+
}
96125
}
126+
}
97127

128+
/// Builds the Agent Control configuration required to execute the application.
129+
fn init_agent_control(
130+
mode: Environment,
131+
base_paths: BasePaths,
132+
) -> Result<(AgentControlRunConfig, Vec<TracingGuardBox>), InitError> {
98133
let agent_control_repository =
99134
ConfigRepositoryFile::new(base_paths.local_dir.clone(), base_paths.remote_dir.clone());
100135

@@ -148,39 +183,6 @@ impl Flags {
148183
},
149184
agent_type_var_constraints,
150185
};
151-
152-
Ok(Command::InitAgentControl(Box::new(run_config), tracer))
153-
}
154-
155-
fn print_version(&self) -> bool {
156-
self.version
157-
}
158-
159-
fn print_debug_info(&self) -> bool {
160-
self.print_debug_info
161-
}
162-
}
163-
164-
/// One-shot operations that can be performed by the agent-control
165-
pub enum OneShotCommand {
166-
/// Print the version of the agent-control and exits
167-
PrintVersion,
168-
/// Print debug information and exits
169-
PrintDebugInfo(Flags),
170-
}
171-
172-
impl OneShotCommand {
173-
/// Runs the one-shot operation
174-
pub fn run_one_shot(&self, env: Environment) {
175-
match self {
176-
OneShotCommand::PrintVersion => {
177-
println!("{}", binary_metadata(env));
178-
}
179-
OneShotCommand::PrintDebugInfo(flags) => {
180-
println!("Printing debug info");
181-
println!("Agent Control Mode: {env:?}");
182-
println!("FLAGS: {flags:#?}");
183-
}
184-
}
186+
Ok((run_config, tracer))
185187
}
186188
}

agent-control/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
pub mod agent_control;
77
pub mod agent_type;
88
pub mod cli;
9+
pub mod command;
910
pub mod config_migrate;
1011
pub mod context;
1112
pub mod event;
12-
pub mod flags;
1313
pub mod health;
1414
pub mod http;
1515
pub mod instrumentation;

agent-control/tests/on_host/cli.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -255,13 +255,12 @@ fn runs_with_no_config() -> Result<(), Box<dyn std::error::Error>> {
255255
// - (\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}) matches the timestamp format.
256256
// Any character match ".*" is used as the raw logging output contains the raw colors unicode
257257
// values: \u{1b}[2m2024\u{1b}[0m \u{1b}[32m INFO\u{1b}[0m \u{1b}[2mnewrelic_agent_control\u{1b}[0m\u{1b}[2m:\u{1b}[0m Creating the global context
258-
cmd.assert().failure().stdout(
259-
predicate::str::is_match(format!(
260-
".*could not read Agent Control config from `{}`.*",
258+
cmd.assert()
259+
.failure()
260+
.stdout(predicate::str::contains(format!(
261+
"could not read Agent Control config from {}",
261262
dir.path().to_string_lossy()
262-
))
263-
.unwrap(),
264-
);
263+
)));
265264

266265
// Env cleanup
267266
unsafe { env::remove_var(env_var_name) };

0 commit comments

Comments
 (0)