use crate::utils::ssh_deploy::{
client::SshClient,
dependencies::{install_docker_if_needed, install_nodejs_if_needed},
errors::DeploymentError,
services::{
await_service_startup, create_docker_service_content, create_systemd_service,
enable_service,
},
types::{DeploymentConfig, NetworkType, ServerConfig},
};
pub async fn deploy_sonic(
client: &mut SshClient,
server_config: &ServerConfig,
deployment_config: &DeploymentConfig,
progress_callback: Option<&crate::prelude::ProgressCallback>,
) -> Result<(), DeploymentError> {
if let Some(callback) = progress_callback {
callback(40, "Cloning Sonic RPC repository");
}
let sonic_dir = format!("{}/sonic-rpc", server_config.install_dir);
clone_sonic_repository(client, &sonic_dir)?;
if let Some(callback) = progress_callback {
callback(50, "Installing dependencies");
}
install_sonic_dependencies(client)?;
if let Some(callback) = progress_callback {
callback(70, "Running setup script");
}
client.execute_command(&format!("cd {} && bash setup.sh", sonic_dir))?;
if let Some(callback) = progress_callback {
callback(80, "Configuring network settings");
}
configure_sonic_network(client, &sonic_dir, deployment_config.network)?;
if let Some(callback) = progress_callback {
callback(90, "Starting Sonic RPC node");
}
start_sonic_node(client, &sonic_dir, deployment_config).await?;
Ok(())
}
fn clone_sonic_repository(client: &mut SshClient, sonic_dir: &str) -> Result<(), DeploymentError> {
if !client.directory_exists(sonic_dir)? {
client.execute_command(&format!(
"git clone https://github.com/sonicfromnewyoke/solana-rpc.git {}",
sonic_dir
))?;
}
Ok(())
}
fn install_sonic_dependencies(client: &mut SshClient) -> Result<(), DeploymentError> {
client.execute_command("sudo apt-get update")?;
client.execute_command(
"sudo apt-get install -y build-essential libssl-dev pkg-config curl git jq",
)?;
install_nodejs_if_needed(client)?;
install_docker_if_needed(client)?;
Ok(())
}
fn configure_sonic_network(
client: &mut SshClient,
sonic_dir: &str,
network: NetworkType,
) -> Result<(), DeploymentError> {
let network_config = match network {
NetworkType::Mainnet => "mainnet",
NetworkType::Testnet => "testnet",
NetworkType::Devnet => "devnet",
};
client.execute_command(&format!(
"cd {} && echo 'SOLANA_NETWORK={}' > .env",
sonic_dir, network_config
))?;
Ok(())
}
async fn start_sonic_node(
client: &mut SshClient,
sonic_dir: &str,
deployment_config: &DeploymentConfig,
) -> Result<(), DeploymentError> {
client.execute_command(&format!("cd {} && docker-compose up -d", sonic_dir))?;
let service_name = format!("sonic-rpc-{}", deployment_config.network);
let service_content = create_docker_service_content(&service_name, sonic_dir, "Sonic RPC Node");
create_systemd_service(client, &service_name, &service_content)?;
enable_service(client, &service_name)?;
await_service_startup(client, &service_name).await?;
Ok(())
}