WIP:adding vm updates
I will overwrite this commit when it's working
This commit is contained in:
parent
cf232f83b3
commit
a0d1c7f95a
@ -22,6 +22,8 @@ pub enum Error {
|
|||||||
StdIo(#[from] std::io::Error),
|
StdIo(#[from] std::io::Error),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
TimeOut(#[from] tokio::time::error::Elapsed),
|
TimeOut(#[from] tokio::time::error::Elapsed),
|
||||||
|
#[error("Could not find VM with ID: {0}")]
|
||||||
|
VmNotFound(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
|
71
src/db/vm.rs
71
src/db/vm.rs
@ -269,6 +269,31 @@ pub struct ActiveVm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ActiveVm {
|
impl ActiveVm {
|
||||||
|
/// total hardware units of this VM
|
||||||
|
fn total_units(&self) -> u64 {
|
||||||
|
// TODO: Optimize this based on price of hardware.
|
||||||
|
// I tried, but this can be done better.
|
||||||
|
// Storage cost should also be based on tier
|
||||||
|
(self.vcpus as u64 * 10)
|
||||||
|
+ ((self.memory_mb + 256) as u64 / 200)
|
||||||
|
+ (self.disk_size_gb as u64 / 10)
|
||||||
|
+ (!self.public_ipv4.is_empty() as u64 * 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns price per minute in nanoLP
|
||||||
|
pub fn price_per_minute(&self) -> u64 {
|
||||||
|
self.total_units() * self.price_per_unit
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_by_uuid(db: &Surreal<Client>, uuid: &str) -> Result<Self, Error> {
|
||||||
|
let contract: Option<Self> =
|
||||||
|
db.query(format!("select * from {ACTIVE_VM}:{uuid};")).await?.take(0)?;
|
||||||
|
match contract {
|
||||||
|
Some(contract) => Ok(contract),
|
||||||
|
None => Err(Error::VmNotFound(uuid.to_string())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn activate(
|
pub async fn activate(
|
||||||
db: &Surreal<Client>,
|
db: &Surreal<Client>,
|
||||||
id: &str,
|
id: &str,
|
||||||
@ -327,6 +352,25 @@ impl ActiveVm {
|
|||||||
NewVmReq::delete(db, id).await?;
|
NewVmReq::delete(db, id).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn change_hostname(
|
||||||
|
db: &Surreal<Client>,
|
||||||
|
id: &str,
|
||||||
|
new_hostname: &str,
|
||||||
|
) -> Result<bool, Error> {
|
||||||
|
let contract: Option<Self> = db
|
||||||
|
.query(format!(
|
||||||
|
"UPDATE {ACTIVE_VM}:{id} SET hostname = '{new_hostname}' RETURN BEFORE;"
|
||||||
|
))
|
||||||
|
.await?
|
||||||
|
.take(0)?;
|
||||||
|
if let Some(contract) = contract {
|
||||||
|
if contract.hostname != new_hostname {
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
@ -344,8 +388,13 @@ pub struct UpdateVmReq {
|
|||||||
pub kernel_sha: String,
|
pub kernel_sha: String,
|
||||||
pub kernel_url: String,
|
pub kernel_url: String,
|
||||||
pub created_at: Datetime,
|
pub created_at: Datetime,
|
||||||
pub price_per_unit: u64,
|
pub error: String,
|
||||||
pub locked_nano: u64,
|
}
|
||||||
|
|
||||||
|
impl UpdateVmReq {
|
||||||
|
fn needs_hw_update(&self) -> Result<bool, Error> {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
@ -431,24 +480,6 @@ impl DeletedVm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActiveVm {
|
|
||||||
/// total hardware units of this VM
|
|
||||||
fn total_units(&self) -> u64 {
|
|
||||||
// TODO: Optimize this based on price of hardware.
|
|
||||||
// I tried, but this can be done better.
|
|
||||||
// Storage cost should also be based on tier
|
|
||||||
(self.vcpus as u64 * 10)
|
|
||||||
+ ((self.memory_mb + 256) as u64 / 200)
|
|
||||||
+ (self.disk_size_gb as u64 / 10)
|
|
||||||
+ (!self.public_ipv4.is_empty() as u64 * 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns price per minute in nanoLP
|
|
||||||
pub fn price_per_minute(&self) -> u64 {
|
|
||||||
self.total_units() * self.price_per_unit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct ActiveVmWithNode {
|
pub struct ActiveVmWithNode {
|
||||||
pub id: RecordId,
|
pub id: RecordId,
|
||||||
|
@ -74,6 +74,25 @@ impl From<db::NewVmResp> for NewVmResp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<UpdateVmReq> for db::UpdateVmReq {
|
||||||
|
fn from(new_vm_req: UpdateVmReq) -> Self {
|
||||||
|
Self {
|
||||||
|
id: RecordId::from((NEW_VM_REQ, nanoid!(40, &ID_ALPHABET))),
|
||||||
|
admin: RecordId::from((ACCOUNT, new_vm_req.admin_pubkey)),
|
||||||
|
vm_node: RecordId::from((VM_NODE, new_vm_req.node_pubkey)),
|
||||||
|
disk_size_gb: new_vm_req.disk_size_gb,
|
||||||
|
vcpus: new_vm_req.vcpus,
|
||||||
|
memory_mb: new_vm_req.memory_mb,
|
||||||
|
kernel_url: new_vm_req.kernel_url,
|
||||||
|
kernel_sha: new_vm_req.kernel_sha,
|
||||||
|
dtrfs_url: new_vm_req.dtrfs_url,
|
||||||
|
dtrfs_sha: new_vm_req.dtrfs_sha,
|
||||||
|
created_at: surrealdb::sql::Datetime::default(),
|
||||||
|
error: String::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<db::UpdateVmReq> for UpdateVmReq {
|
impl From<db::UpdateVmReq> for UpdateVmReq {
|
||||||
fn from(update_vm_req: db::UpdateVmReq) -> Self {
|
fn from(update_vm_req: db::UpdateVmReq) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -207,7 +207,9 @@ impl BrainVmCli for VmCliServer {
|
|||||||
async fn new_vm(&self, req: Request<NewVmReq>) -> Result<Response<NewVmResp>, Status> {
|
async fn new_vm(&self, req: Request<NewVmReq>) -> Result<Response<NewVmResp>, Status> {
|
||||||
let req = check_sig_from_req(req)?;
|
let req = check_sig_from_req(req)?;
|
||||||
info!("New VM requested via CLI: {req:?}");
|
info!("New VM requested via CLI: {req:?}");
|
||||||
if db::general::Account::is_banned_by_node(&self.db, &req.admin_pubkey, &req.node_pubkey).await? {
|
if db::general::Account::is_banned_by_node(&self.db, &req.admin_pubkey, &req.node_pubkey)
|
||||||
|
.await?
|
||||||
|
{
|
||||||
return Err(Status::permission_denied("This operator banned you. What did you do?"));
|
return Err(Status::permission_denied("This operator banned you. What did you do?"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,12 +225,14 @@ impl BrainVmCli for VmCliServer {
|
|||||||
new_vm_req.submit(&self.db).await?;
|
new_vm_req.submit(&self.db).await?;
|
||||||
|
|
||||||
match oneshot_rx.await {
|
match oneshot_rx.await {
|
||||||
Ok(Err(db::Error::TimeOut(_))) => Err(Status::deadline_exceeded("Request failed due to timeout. Please try again later or contact the DeTEE devs team.")),
|
Ok(Err(db::Error::TimeOut(_))) => Err(Status::deadline_exceeded(
|
||||||
|
"Network timeout. Please try again later or contact the DeTEE devs team.",
|
||||||
|
)),
|
||||||
Ok(new_vm_resp) => Ok(Response::new(new_vm_resp?.into())),
|
Ok(new_vm_resp) => Ok(Response::new(new_vm_resp?.into())),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Something weird happened. Reached error {e:?}");
|
log::error!("Something weird happened. Reached error {e:?}");
|
||||||
Err(Status::unknown(
|
Err(Status::unknown(
|
||||||
"Request failed due to unknown error. Please try again or contact the DeTEE devs team.",
|
"Unknown error. Please try again or contact the DeTEE devs team.",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,8 @@ use dotenv::dotenv;
|
|||||||
use hyper_util::rt::TokioIo;
|
use hyper_util::rt::TokioIo;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use surreal_brain::grpc::{
|
use surreal_brain::grpc::general::GeneralCliServer;
|
||||||
general::GeneralCliServer,
|
use surreal_brain::grpc::vm::{VmCliServer, VmDaemonServer};
|
||||||
vm::{VmCliServer, VmDaemonServer},
|
|
||||||
};
|
|
||||||
use surrealdb::engine::remote::ws::Client;
|
use surrealdb::engine::remote::ws::Client;
|
||||||
use surrealdb::Surreal;
|
use surrealdb::Surreal;
|
||||||
use tokio::io::DuplexStream;
|
use tokio::io::DuplexStream;
|
||||||
|
Loading…
Reference in New Issue
Block a user