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),
|
||||
#[error(transparent)]
|
||||
TimeOut(#[from] tokio::time::error::Elapsed),
|
||||
#[error("Could not find VM with ID: {0}")]
|
||||
VmNotFound(String),
|
||||
}
|
||||
|
||||
pub mod prelude {
|
||||
|
71
src/db/vm.rs
71
src/db/vm.rs
@ -269,6 +269,31 @@ pub struct 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(
|
||||
db: &Surreal<Client>,
|
||||
id: &str,
|
||||
@ -327,6 +352,25 @@ impl ActiveVm {
|
||||
NewVmReq::delete(db, id).await?;
|
||||
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)]
|
||||
@ -344,8 +388,13 @@ pub struct UpdateVmReq {
|
||||
pub kernel_sha: String,
|
||||
pub kernel_url: String,
|
||||
pub created_at: Datetime,
|
||||
pub price_per_unit: u64,
|
||||
pub locked_nano: u64,
|
||||
pub error: String,
|
||||
}
|
||||
|
||||
impl UpdateVmReq {
|
||||
fn needs_hw_update(&self) -> Result<bool, Error> {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
#[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)]
|
||||
pub struct ActiveVmWithNode {
|
||||
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 {
|
||||
fn from(update_vm_req: db::UpdateVmReq) -> Self {
|
||||
Self {
|
||||
|
@ -207,7 +207,9 @@ impl BrainVmCli for VmCliServer {
|
||||
async fn new_vm(&self, req: Request<NewVmReq>) -> Result<Response<NewVmResp>, Status> {
|
||||
let req = check_sig_from_req(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?"));
|
||||
}
|
||||
|
||||
@ -223,12 +225,14 @@ impl BrainVmCli for VmCliServer {
|
||||
new_vm_req.submit(&self.db).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())),
|
||||
Err(e) => {
|
||||
log::error!("Something weird happened. Reached error {e:?}");
|
||||
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 std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
use surreal_brain::grpc::{
|
||||
general::GeneralCliServer,
|
||||
vm::{VmCliServer, VmDaemonServer},
|
||||
};
|
||||
use surreal_brain::grpc::general::GeneralCliServer;
|
||||
use surreal_brain::grpc::vm::{VmCliServer, VmDaemonServer};
|
||||
use surrealdb::engine::remote::ws::Client;
|
||||
use surrealdb::Surreal;
|
||||
use tokio::io::DuplexStream;
|
||||
|
Loading…
Reference in New Issue
Block a user