Skip to content

Commit 0106128

Browse files
committed
Refactor main lib.rs
Signed-off-by: Guvenc Gulce <[email protected]>
1 parent 6a9c270 commit 0106128

File tree

4 files changed

+266
-193
lines changed

4 files changed

+266
-193
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ members = [
1111
resolver = "2"
1212

1313
[workspace.package]
14-
version = "0.2.1"
14+
version = "0.2.0"
1515
edition = "2021"
1616

1717
[workspace.dependencies]

feos/src/lib.rs

Lines changed: 14 additions & 185 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,15 @@
1+
mod setup;
2+
13
use anyhow::Result;
2-
use feos_proto::{
3-
host_service::host_service_server::HostServiceServer,
4-
image_service::image_service_server::ImageServiceServer,
5-
vm_service::vm_service_server::VmServiceServer,
6-
};
7-
use feos_utils::filesystem::mount_virtual_filesystems;
8-
use feos_utils::host::info::is_running_on_vm;
9-
use feos_utils::host::memory::configure_hugepages;
10-
use feos_utils::network::{configure_network_devices, configure_sriov};
11-
use host_service::{
12-
api::HostApiHandler, dispatcher::HostServiceDispatcher, Command as HostCommand, RestartSignal,
13-
};
14-
use image_service::{
15-
api::ImageApiHandler, dispatcher::ImageServiceDispatcher, filestore::FileStore,
16-
worker::Orchestrator, IMAGE_DIR, IMAGE_SERVICE_SOCKET,
17-
};
4+
use host_service::RestartSignal;
5+
use image_service::IMAGE_SERVICE_SOCKET;
186
use log::{error, info, warn};
19-
use nix::libc;
207
use nix::unistd::Uid;
8+
use setup::*;
219
use std::env;
22-
use std::ffi::CString;
23-
use std::os::unix::ffi::OsStringExt;
24-
use std::os::unix::fs::PermissionsExt;
25-
use std::path::Path;
26-
use tokio::fs::{self, File};
27-
use tokio::{net::UnixListener, sync::mpsc};
10+
use tokio::{fs, net::UnixListener, sync::mpsc};
2811
use tokio_stream::wrappers::UnixListenerStream;
2912
use tonic::transport::Server;
30-
use vm_service::{
31-
api::VmApiHandler, dispatcher::VmServiceDispatcher, Command as VmCommand, DEFAULT_VM_DB_URL,
32-
VM_API_SOCKET_DIR, VM_CONSOLE_DIR,
33-
};
34-
35-
const VFS_NUM: u32 = 125;
36-
const HUGEPAGES_NUM: u32 = 1024;
3713

3814
pub async fn run_server(restarted_after_upgrade: bool) -> Result<()> {
3915
println!(
@@ -51,7 +27,7 @@ pub async fn run_server(restarted_after_upgrade: bool) -> Result<()> {
5127

5228
let log_handle = feos_utils::feos_logger::Builder::new()
5329
.filter_level(log::LevelFilter::Info)
54-
.max_history(100)
30+
.max_history(150)
5531
.init()
5632
.expect("Failed to initialize feos_logger");
5733

@@ -61,119 +37,21 @@ pub async fn run_server(restarted_after_upgrade: bool) -> Result<()> {
6137

6238
if !restarted_after_upgrade {
6339
if std::process::id() == 1 {
64-
info!("MAIN: Performing first-boot initialization...");
65-
info!("MAIN: Mounting virtual filesystems...");
66-
mount_virtual_filesystems();
67-
68-
info!("MAIN: Configuring hugepages...");
69-
if let Err(e) = configure_hugepages(HUGEPAGES_NUM).await {
70-
warn!("Failed to configure hugepages: {e}");
71-
}
72-
73-
let is_on_vm = is_running_on_vm().await.unwrap_or_else(|e| {
74-
error!("Error checking VM status: {e}");
75-
false // Default to false in case of error
76-
});
77-
78-
info!("MAIN: Configuring network devices...");
79-
if let Some((delegated_prefix, delegated_prefix_length)) = configure_network_devices()
80-
.await
81-
.expect("could not configure network devices")
82-
{
83-
info!("MAIN: Delegated prefix: {delegated_prefix}/{delegated_prefix_length}");
84-
}
85-
86-
if !is_on_vm {
87-
info!("configuring sriov...");
88-
if let Err(e) = configure_sriov(VFS_NUM).await {
89-
warn!("failed to configure sriov: {e}")
90-
}
91-
}
40+
perform_first_boot_initialization().await?;
9241
}
9342
} else {
9443
info!("MAIN: Skipping one-time initialization on restart after upgrade.");
9544
}
9645

97-
dotenvy::dotenv().ok();
98-
99-
let db_url = env::var("DATABASE_URL").unwrap_or_else(|_| {
100-
info!("MAIN: DATABASE_URL not set, using default '{DEFAULT_VM_DB_URL}'");
101-
DEFAULT_VM_DB_URL.to_string()
102-
});
103-
if let Some(db_path_str) = db_url.strip_prefix("sqlite:") {
104-
let db_path = Path::new(db_path_str);
105-
if let Some(db_dir) = db_path.parent() {
106-
info!(
107-
"MAIN: Ensuring database directory '{}' exists...",
108-
db_dir.display()
109-
);
110-
fs::create_dir_all(db_dir).await?;
111-
}
112-
if !db_path.exists() {
113-
info!(
114-
"MAIN: Database file does not exist, creating at '{}'...",
115-
db_path.display()
116-
);
117-
File::create(db_path).await?;
118-
}
119-
}
46+
let db_url = setup_database().await?;
12047

12148
let (restart_tx, mut restart_rx) = mpsc::channel::<RestartSignal>(1);
12249

123-
info!("MAIN: Ensuring VM socket directory '{VM_API_SOCKET_DIR}' exists...");
124-
fs::create_dir_all(VM_API_SOCKET_DIR).await?;
125-
info!("MAIN: Directory check complete. Path '{VM_API_SOCKET_DIR}' is ready.");
50+
let vm_service = initialize_vm_service(&db_url).await?;
12651

127-
info!("MAIN: Ensuring VM console directory '{VM_CONSOLE_DIR}' exists...");
128-
fs::create_dir_all(VM_CONSOLE_DIR).await?;
129-
info!("MAIN: Directory check complete. Path '{VM_CONSOLE_DIR}' is ready.");
52+
let host_service = initialize_host_service(restart_tx.clone(), log_handle);
13053

131-
let (vm_tx, vm_rx) = mpsc::channel::<VmCommand>(32);
132-
let vm_dispatcher = VmServiceDispatcher::new(vm_rx, &db_url).await?;
133-
tokio::spawn(async move {
134-
vm_dispatcher.run().await;
135-
});
136-
let vm_api_handler = VmApiHandler::new(vm_tx);
137-
let vm_service = VmServiceServer::new(vm_api_handler);
138-
info!("MAIN: VM Service is configured.");
139-
140-
let (host_tx, host_rx) = mpsc::channel::<HostCommand>(32);
141-
let host_dispatcher = HostServiceDispatcher::new(host_rx, restart_tx.clone(), log_handle);
142-
tokio::spawn(async move {
143-
host_dispatcher.run().await;
144-
});
145-
let host_api_handler = HostApiHandler::new(host_tx);
146-
let host_service = HostServiceServer::new(host_api_handler);
147-
info!("MAIN: Host Service is configured.");
148-
149-
info!("MAIN: Ensuring image directory '{IMAGE_DIR}' exists...");
150-
fs::create_dir_all(IMAGE_DIR).await?;
151-
info!("MAIN: Directory check complete. Path '{IMAGE_DIR}' is ready.");
152-
153-
let filestore_actor = FileStore::new();
154-
let filestore_tx = filestore_actor.get_command_sender();
155-
tokio::spawn(async move {
156-
filestore_actor.run().await;
157-
});
158-
info!("MAIN: FileStore actor for Image Service has been started.");
159-
160-
let orchestrator_actor = Orchestrator::new(filestore_tx);
161-
let orchestrator_tx = orchestrator_actor.get_command_sender();
162-
tokio::spawn(async move {
163-
orchestrator_actor.run().await;
164-
});
165-
info!("MAIN: Orchestrator actor for Image Service has been started.");
166-
167-
let grpc_dispatcher = ImageServiceDispatcher::new(orchestrator_tx);
168-
let grpc_dispatcher_tx = grpc_dispatcher.get_command_sender();
169-
tokio::spawn(async move {
170-
grpc_dispatcher.run().await;
171-
});
172-
info!("MAIN: gRPC Dispatcher for Image Service has been started.");
173-
174-
let image_api_handler = ImageApiHandler::new(grpc_dispatcher_tx);
175-
let image_service = ImageServiceServer::new(image_api_handler);
176-
info!("MAIN: Image Service is configured.");
54+
let image_service = initialize_image_service().await?;
17755

17856
let tcp_addr = "[::]:1337".parse().unwrap();
17957
let tcp_server = Server::builder()
@@ -203,58 +81,9 @@ pub async fn run_server(restarted_after_upgrade: bool) -> Result<()> {
20381
}
20482
},
20583
Some(RestartSignal(new_binary_path)) = restart_rx.recv() => {
206-
info!("MAIN: Upgrade signal received. New binary at {new_binary_path:?}. Preparing to execv.");
207-
208-
let current_exe = match std::env::current_exe() {
209-
Ok(path) => path,
210-
Err(e) => panic!("FATAL: Could not get current executable path: {e}"),
211-
};
212-
info!("MAIN: Current binary is at {:?}", &current_exe);
213-
214-
let rename_result = std::fs::rename(&new_binary_path, &current_exe);
215-
216-
match rename_result {
217-
Ok(_) => {
218-
info!("MAIN: Successfully replaced on-disk binary via atomic rename.");
219-
}
220-
Err(e) if e.raw_os_error() == Some(libc::EXDEV) => {
221-
info!("MAIN: Cross-device link detected. Falling back to copy-then-rename strategy.");
222-
let staging_path = current_exe.with_extension("staging");
223-
if let Err(copy_err) = std::fs::copy(&new_binary_path, &staging_path) {
224-
error!("CRITICAL: Failed to copy new binary to staging path {:?}: {}. Aborting upgrade.", &staging_path, copy_err);
225-
return Ok(());
226-
}
227-
if let Err(perm_err) = std::fs::set_permissions(&staging_path, std::fs::Permissions::from_mode(0o755)) {
228-
error!("CRITICAL: Failed to set permissions on staged binary {:?}: {}. Aborting upgrade.", &staging_path, perm_err);
229-
let _ = std::fs::remove_file(&staging_path);
230-
return Ok(());
231-
}
232-
if let Err(final_rename_err) = std::fs::rename(&staging_path, &current_exe) {
233-
error!("CRITICAL: Failed to perform final atomic rename from {:?}: {}. Aborting upgrade.", &staging_path, final_rename_err);
234-
let _ = std::fs::remove_file(&staging_path);
235-
return Ok(());
236-
}
237-
let _ = std::fs::remove_file(&new_binary_path);
238-
info!("MAIN: Successfully replaced on-disk binary via copy-then-rename.");
239-
}
240-
Err(e) => {
241-
error!("CRITICAL: Failed to rename new binary into place with an unexpected error: {e}. Aborting upgrade.");
242-
return Ok(());
243-
}
244-
}
245-
246-
let mut args: Vec<String> = std::env::args().collect();
247-
let restart_flag = "--restarted-after-upgrade";
248-
if !args.contains(&restart_flag.to_string()) {
249-
args.push(restart_flag.to_string());
84+
if let Err(e) = handle_upgrade(&new_binary_path) {
85+
error!("Upgrade failed: {e}");
25086
}
251-
252-
let cstr_args: Vec<CString> = args.into_iter().map(|arg| CString::new(arg).unwrap()).collect();
253-
let cstr_path = CString::new(current_exe.into_os_string().into_vec()).unwrap();
254-
255-
info!("MAIN: Executing new binary with arguments: {:?}", &cstr_args);
256-
let Err(e) = nix::unistd::execv(&cstr_path, &cstr_args);
257-
panic!("FATAL: execv failed after replacing binary: {e}");
25887
}
25988
};
26089

0 commit comments

Comments
 (0)