Skip to content

Commit 70a664b

Browse files
Martin Moreira de Jesusnoetarbouriech
andcommitted
feat(node-agent): implement node lifecycle
Add method to connect to cluster and stream node status. Retries in case of the connection closing. Signed-off-by: Martin Moreira de Jesus <martin.moreiradj@icloud.com> Signed-off-by: Noé Tarbouriech <noe.tarbouriech@etu.umontpellier.fr> Co-Authored-By: Noé Tarbouriech <noe.tarbouriech@etu.umontpellier.fr>
1 parent ce3d051 commit 70a664b

7 files changed

Lines changed: 308 additions & 9 deletions

File tree

Cargo.lock

Lines changed: 108 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node-agent/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ tracing-subscriber = "0.3.17"
1919
tracing-log = "0.1.3"
2020
uuid = { version = "1.4.1", features = ["v4", "macro-diagnostics", "fast-rng"] }
2121
tower-http = { version = "0.4.3", features = ["trace"] }
22+
clap = { version = "4.4.2", features = ["env", "derive"] }
23+
clap-verbosity-flag = "2.0.1"
24+
async-stream = "0.3.5"
25+
sysinfo = "0.29.9"
2226

2327
[build-dependencies]
2428
tonic-build = "0.9.2"

node-agent/src/args.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//! Command-line arguments.
2+
use clap::Parser;
3+
use clap_verbosity_flag::{InfoLevel, Verbosity};
4+
5+
/// Scheduler service for the Orka container orchestration system.
6+
#[derive(Parser, Debug)]
7+
#[command(author, version, about, long_about = None)]
8+
pub struct CliArguments {
9+
#[arg(long, default_value_t = 3, env)]
10+
pub lifecycle_retries: i32,
11+
12+
/// The port to start the node agent on.
13+
#[arg(long, default_value_t = 50052, env)]
14+
pub node_agent_port: u16,
15+
16+
/// The address of the scheduler to connect the node agent to.
17+
#[arg(long, default_value = "[::]", env)]
18+
pub scheduler_address: String,
19+
20+
/// The port of the scheduler to connect the node agent to.
21+
#[arg(long, default_value_t = 50051, env)]
22+
pub scheduler_port: u16,
23+
24+
/// Verbosity level.
25+
#[command(flatten)]
26+
pub verbose: Verbosity<InfoLevel>,
27+
}

node-agent/src/main.rs

Lines changed: 108 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,77 @@
1+
mod args;
12
mod workload_manager;
23

3-
use orka_proto::node_agent::Workload;
4+
use clap::Parser;
5+
use orka_proto::{node_agent::Workload, scheduler_agent::{lifecycle_service_client::LifecycleServiceClient, ConnectionRequest, status_update_service_client::StatusUpdateServiceClient}};
6+
use tracing::{info, error};
7+
use uuid::Uuid;
48
use workload_manager::container::client::ContainerClient;
9+
use anyhow::Result;
10+
use tracing_log::AsTrace;
11+
12+
use crate::{workload_manager::container::metrics::metrics::any_to_resource, args::CliArguments};
13+
use crate::workload_manager::node::metrics::stream_node_status;
14+
15+
async fn execute_node_lifecycle(
16+
node_id: Uuid,
17+
node_agent_port: u16,
18+
scheduler_connection_string: String,
19+
) -> Result<()> {
20+
info!(
21+
"Connecting to scheduler on {}",
22+
scheduler_connection_string
23+
);
24+
25+
loop {
26+
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
527

6-
use crate::workload_manager::container::metrics::metrics::any_to_resource;
28+
let mut lifecycle_client =
29+
match LifecycleServiceClient::connect(scheduler_connection_string.clone()).await {
30+
Ok(client) => Ok(client),
31+
Err(e) => {
32+
error!("Failed to connect to scheduler: {:?}", e);
33+
Err(e)
34+
}
35+
}?;
36+
37+
match lifecycle_client
38+
.join_cluster(ConnectionRequest {
39+
id: node_id.to_string(),
40+
port: node_agent_port as u32,
41+
})
42+
.await
43+
{
44+
Ok(_) => Ok(()),
45+
Err(e) => {
46+
error!("Failed to join cluster: {:?}", e);
47+
Err(e)
48+
}
49+
}?;
50+
51+
info!("Joined cluster");
52+
53+
let mut client =
54+
match StatusUpdateServiceClient::connect(scheduler_connection_string.clone()).await {
55+
Ok(client) => Ok(client),
56+
Err(e) => {
57+
error!("Failed to connect to scheduler: {:?}", e);
58+
Err(e)
59+
}
60+
}?;
61+
62+
match stream_node_status(node_id, &mut client, 15).await {
63+
Ok(_) => {
64+
info!("Node status stream ended, retrying");
65+
}
66+
Err(error) => {
67+
error!(
68+
"Node status stream failed: {:?}, reconnecting to scheduler",
69+
error
70+
);
71+
}
72+
};
73+
}
74+
}
775

876
const CID: &str = "nginx";
977

@@ -51,4 +119,42 @@ async fn main() {
51119
Ok(_) => panic!("Workload should not exist"),
52120
Err(_) => println!("Workload does not exist"),
53121
};
122+
123+
let args = CliArguments::parse();
124+
125+
tracing_subscriber::fmt()
126+
.with_max_level(args.verbose.log_level_filter().as_trace())
127+
.init();
128+
129+
info!(
130+
app_name = env!("CARGO_PKG_NAME"),
131+
app_version = env!("CARGO_PKG_VERSION"),
132+
"Starting",
133+
);
134+
135+
info!("Arguments: {:?}", args);
136+
137+
let scheduler_connection_string =
138+
format!("http://{}:{}", args.scheduler_address, args.scheduler_port);
139+
140+
let node_id = Uuid::new_v4();
141+
142+
let retries = args.lifecycle_retries;
143+
144+
for _ in 0..retries {
145+
match execute_node_lifecycle(
146+
node_id,
147+
args.node_agent_port,
148+
scheduler_connection_string.clone(),
149+
)
150+
.await
151+
{
152+
Ok(_) => {
153+
// will never be reached
154+
}
155+
Err(e) => {
156+
error!("Failed to execute node lifecycle: {:?}", e);
157+
}
158+
}
159+
}
54160
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
pub mod container;
2+
pub mod node;

0 commit comments

Comments
 (0)