new credits system
This commit is contained in:
parent
ee1b12f85f
commit
ef0b6972fe
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1011,7 +1011,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "detee-shared"
|
name = "detee-shared"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+ssh://git@gitea.detee.cloud/testnet/proto?branch=surreal_brain_app#0b195b4589e4ec689af7ddca27dc051716ecee78"
|
source = "git+ssh://git@gitea.detee.cloud/testnet/proto?branch=credits#09bca21eca5513bca73a380f295e3ce49d9cc6d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode 2.0.1",
|
"bincode 2.0.1",
|
||||||
"prost",
|
"prost",
|
||||||
|
@ -15,7 +15,7 @@ serde_yaml = "0.9.34"
|
|||||||
surrealdb = "2.2.2"
|
surrealdb = "2.2.2"
|
||||||
tokio = { version = "1.44.2", features = ["macros", "rt-multi-thread"] }
|
tokio = { version = "1.44.2", features = ["macros", "rt-multi-thread"] }
|
||||||
tonic = { version = "0.12", features = ["tls"] }
|
tonic = { version = "0.12", features = ["tls"] }
|
||||||
detee-shared = { git = "ssh://git@gitea.detee.cloud/testnet/proto", branch = "surreal_brain_app" }
|
detee-shared = { git = "ssh://git@gitea.detee.cloud/testnet/proto", branch = "credits" }
|
||||||
ed25519-dalek = "2.1.1"
|
ed25519-dalek = "2.1.1"
|
||||||
bs58 = "0.5.1"
|
bs58 = "0.5.1"
|
||||||
tokio-stream = "0.1.17"
|
tokio-stream = "0.1.17"
|
||||||
|
78
src/db/vm.rs
78
src/db/vm.rs
@ -33,7 +33,7 @@ pub struct VmNode {
|
|||||||
pub avail_ipv6: u32,
|
pub avail_ipv6: u32,
|
||||||
pub avail_ports: u32,
|
pub avail_ports: u32,
|
||||||
pub max_ports_per_vm: u32,
|
pub max_ports_per_vm: u32,
|
||||||
pub price: u64,
|
pub price_per_slot: u64,
|
||||||
pub connected_at: Datetime,
|
pub connected_at: Datetime,
|
||||||
pub disconnected_at: Datetime,
|
pub disconnected_at: Datetime,
|
||||||
}
|
}
|
||||||
@ -59,9 +59,9 @@ impl VmNode {
|
|||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct VmNodeResources {
|
pub struct VmNodeResources {
|
||||||
pub avail_mem_mb: u32,
|
pub avail_mem_mib: u32,
|
||||||
pub avail_vcpus: u32,
|
pub avail_vcpus: u32,
|
||||||
pub avail_storage_gbs: u32,
|
pub avail_storage_mib: u32,
|
||||||
pub avail_ipv4: u32,
|
pub avail_ipv4: u32,
|
||||||
pub avail_ipv6: u32,
|
pub avail_ipv6: u32,
|
||||||
pub avail_ports: u32,
|
pub avail_ports: u32,
|
||||||
@ -113,8 +113,8 @@ impl VmNodeWithReports {
|
|||||||
filters.offers_ipv4 as u32,
|
filters.offers_ipv4 as u32,
|
||||||
filters.offers_ipv6 as u32,
|
filters.offers_ipv6 as u32,
|
||||||
filters.vcpus,
|
filters.vcpus,
|
||||||
filters.memory_mb,
|
filters.memory_mib,
|
||||||
filters.storage_gb
|
filters.storage_mib
|
||||||
);
|
);
|
||||||
if !filters.city.is_empty() {
|
if !filters.city.is_empty() {
|
||||||
query += &format!("&& city = '{}' ", filters.city);
|
query += &format!("&& city = '{}' ", filters.city);
|
||||||
@ -170,15 +170,15 @@ pub struct NewVmReq {
|
|||||||
pub extra_ports: Vec<u32>,
|
pub extra_ports: Vec<u32>,
|
||||||
pub public_ipv4: bool,
|
pub public_ipv4: bool,
|
||||||
pub public_ipv6: bool,
|
pub public_ipv6: bool,
|
||||||
pub disk_size_gb: u32,
|
pub disk_size_mib: u32,
|
||||||
pub vcpus: u32,
|
pub vcpus: u32,
|
||||||
pub memory_mb: u32,
|
pub memory_mib: u32,
|
||||||
pub dtrfs_url: String,
|
pub dtrfs_url: String,
|
||||||
pub dtrfs_sha: String,
|
pub dtrfs_sha: String,
|
||||||
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 price_per_slot: u64,
|
||||||
pub locked_nano: u64,
|
pub locked_nano: u64,
|
||||||
pub error: String,
|
pub error: String,
|
||||||
}
|
}
|
||||||
@ -274,12 +274,12 @@ impl NewVmReq {
|
|||||||
|
|
||||||
COMMIT TRANSACTION;",
|
COMMIT TRANSACTION;",
|
||||||
self.vcpus,
|
self.vcpus,
|
||||||
self.memory_mb,
|
self.memory_mib,
|
||||||
self.disk_size_gb,
|
self.disk_size_mib,
|
||||||
self.extra_ports,
|
self.extra_ports,
|
||||||
self.public_ipv4,
|
self.public_ipv4,
|
||||||
self.public_ipv6,
|
self.public_ipv6,
|
||||||
self.price_per_unit
|
self.price_per_slot
|
||||||
);
|
);
|
||||||
|
|
||||||
log::trace!("submit_new_vm_req query: {tx_query}");
|
log::trace!("submit_new_vm_req query: {tx_query}");
|
||||||
@ -404,9 +404,9 @@ pub struct ActiveVm {
|
|||||||
pub mapped_ports: Vec<(u32, u32)>,
|
pub mapped_ports: Vec<(u32, u32)>,
|
||||||
pub public_ipv4: String,
|
pub public_ipv4: String,
|
||||||
pub public_ipv6: String,
|
pub public_ipv6: String,
|
||||||
pub disk_size_gb: u32,
|
pub disk_size_mib: u32,
|
||||||
pub vcpus: u32,
|
pub vcpus: u32,
|
||||||
pub memory_mb: u32,
|
pub memory_mib: u32,
|
||||||
pub dtrfs_sha: String,
|
pub dtrfs_sha: String,
|
||||||
pub kernel_sha: String,
|
pub kernel_sha: String,
|
||||||
pub created_at: Datetime,
|
pub created_at: Datetime,
|
||||||
@ -422,8 +422,8 @@ impl ActiveVm {
|
|||||||
// I tried, but this can be done better.
|
// I tried, but this can be done better.
|
||||||
// Storage cost should also be based on tier
|
// Storage cost should also be based on tier
|
||||||
(self.vcpus as u64 * 10)
|
(self.vcpus as u64 * 10)
|
||||||
+ ((self.memory_mb + 256) as u64 / 200)
|
+ ((self.memory_mib + 256) as u64 / 200)
|
||||||
+ (self.disk_size_gb as u64 / 10)
|
+ (self.disk_size_mib as u64 / 10)
|
||||||
+ (!self.public_ipv4.is_empty() as u64 * 10)
|
+ (!self.public_ipv4.is_empty() as u64 * 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,13 +483,13 @@ impl ActiveVm {
|
|||||||
mapped_ports,
|
mapped_ports,
|
||||||
public_ipv4,
|
public_ipv4,
|
||||||
public_ipv6,
|
public_ipv6,
|
||||||
disk_size_gb: new_vm_req.disk_size_gb,
|
disk_size_mib: new_vm_req.disk_size_mib,
|
||||||
vcpus: new_vm_req.vcpus,
|
vcpus: new_vm_req.vcpus,
|
||||||
memory_mb: new_vm_req.memory_mb,
|
memory_mib: new_vm_req.memory_mib,
|
||||||
dtrfs_sha: new_vm_req.dtrfs_sha,
|
dtrfs_sha: new_vm_req.dtrfs_sha,
|
||||||
kernel_sha: new_vm_req.kernel_sha,
|
kernel_sha: new_vm_req.kernel_sha,
|
||||||
created_at: new_vm_req.created_at.clone(),
|
created_at: new_vm_req.created_at.clone(),
|
||||||
price_per_unit: new_vm_req.price_per_unit,
|
price_per_unit: new_vm_req.price_per_slot,
|
||||||
locked_nano: new_vm_req.locked_nano,
|
locked_nano: new_vm_req.locked_nano,
|
||||||
collected_at: new_vm_req.created_at,
|
collected_at: new_vm_req.created_at,
|
||||||
};
|
};
|
||||||
@ -517,11 +517,11 @@ impl ActiveVm {
|
|||||||
if update_vm_req.vcpus > 0 {
|
if update_vm_req.vcpus > 0 {
|
||||||
active_vm.vcpus = update_vm_req.vcpus;
|
active_vm.vcpus = update_vm_req.vcpus;
|
||||||
}
|
}
|
||||||
if update_vm_req.memory_mb > 0 {
|
if update_vm_req.memory_mib > 0 {
|
||||||
active_vm.memory_mb = update_vm_req.memory_mb;
|
active_vm.memory_mib = update_vm_req.memory_mib;
|
||||||
}
|
}
|
||||||
if update_vm_req.disk_size_gb > 0 {
|
if update_vm_req.disk_mib > 0 {
|
||||||
active_vm.disk_size_gb = update_vm_req.disk_size_gb;
|
active_vm.disk_size_mib = update_vm_req.disk_mib;
|
||||||
}
|
}
|
||||||
if !update_vm_req.dtrfs_sha.is_empty() && !update_vm_req.kernel_sha.is_empty() {
|
if !update_vm_req.dtrfs_sha.is_empty() && !update_vm_req.kernel_sha.is_empty() {
|
||||||
active_vm.dtrfs_sha = update_vm_req.dtrfs_sha;
|
active_vm.dtrfs_sha = update_vm_req.dtrfs_sha;
|
||||||
@ -670,9 +670,9 @@ pub struct UpdateVmReq {
|
|||||||
pub admin: RecordId,
|
pub admin: RecordId,
|
||||||
#[serde(rename = "out")]
|
#[serde(rename = "out")]
|
||||||
pub vm_node: RecordId,
|
pub vm_node: RecordId,
|
||||||
pub disk_size_gb: u32,
|
pub disk_mib: u32,
|
||||||
pub vcpus: u32,
|
pub vcpus: u32,
|
||||||
pub memory_mb: u32,
|
pub memory_mib: u32,
|
||||||
pub dtrfs_url: String,
|
pub dtrfs_url: String,
|
||||||
pub dtrfs_sha: String,
|
pub dtrfs_sha: String,
|
||||||
pub kernel_sha: String,
|
pub kernel_sha: String,
|
||||||
@ -704,9 +704,9 @@ impl From<UpdateVmReq> for UpdateVmEvent {
|
|||||||
vm_id: RecordId::from((VM_UPDATE_EVENT, update_vm_req.id.key().to_string())),
|
vm_id: RecordId::from((VM_UPDATE_EVENT, update_vm_req.id.key().to_string())),
|
||||||
admin: update_vm_req.admin,
|
admin: update_vm_req.admin,
|
||||||
vm_node: update_vm_req.vm_node,
|
vm_node: update_vm_req.vm_node,
|
||||||
disk_size_gb: update_vm_req.disk_size_gb,
|
disk_size_gb: update_vm_req.disk_mib,
|
||||||
vcpus: update_vm_req.vcpus,
|
vcpus: update_vm_req.vcpus,
|
||||||
memory_mb: update_vm_req.memory_mb,
|
memory_mb: update_vm_req.memory_mib,
|
||||||
dtrfs_url: update_vm_req.dtrfs_url,
|
dtrfs_url: update_vm_req.dtrfs_url,
|
||||||
dtrfs_sha: update_vm_req.dtrfs_sha,
|
dtrfs_sha: update_vm_req.dtrfs_sha,
|
||||||
kernel_sha: update_vm_req.kernel_sha,
|
kernel_sha: update_vm_req.kernel_sha,
|
||||||
@ -747,9 +747,9 @@ impl UpdateVmReq {
|
|||||||
self.vm_node = contract.vm_node;
|
self.vm_node = contract.vm_node;
|
||||||
|
|
||||||
if !((self.vcpus != 0 && contract.vcpus != self.vcpus)
|
if !((self.vcpus != 0 && contract.vcpus != self.vcpus)
|
||||||
|| (self.memory_mb != 0 && contract.memory_mb != self.memory_mb)
|
|| (self.memory_mib != 0 && contract.memory_mib != self.memory_mib)
|
||||||
|| (!self.dtrfs_sha.is_empty() && contract.dtrfs_sha != self.dtrfs_sha)
|
|| (!self.dtrfs_sha.is_empty() && contract.dtrfs_sha != self.dtrfs_sha)
|
||||||
|| (self.disk_size_gb != 0 && contract.disk_size_gb != self.disk_size_gb))
|
|| (self.disk_mib != 0 && contract.disk_size_mib != self.disk_mib))
|
||||||
{
|
{
|
||||||
return Ok(Some(false));
|
return Ok(Some(false));
|
||||||
}
|
}
|
||||||
@ -799,9 +799,9 @@ impl From<ActiveVm> for DeletedVm {
|
|||||||
mapped_ports: active_vm.mapped_ports,
|
mapped_ports: active_vm.mapped_ports,
|
||||||
public_ipv4: active_vm.public_ipv4,
|
public_ipv4: active_vm.public_ipv4,
|
||||||
public_ipv6: active_vm.public_ipv6,
|
public_ipv6: active_vm.public_ipv6,
|
||||||
disk_size_gb: active_vm.disk_size_gb,
|
disk_size_gb: active_vm.disk_size_mib,
|
||||||
vcpus: active_vm.vcpus,
|
vcpus: active_vm.vcpus,
|
||||||
memory_mb: active_vm.memory_mb,
|
memory_mb: active_vm.memory_mib,
|
||||||
dtrfs_sha: active_vm.dtrfs_sha,
|
dtrfs_sha: active_vm.dtrfs_sha,
|
||||||
kernel_sha: active_vm.kernel_sha,
|
kernel_sha: active_vm.kernel_sha,
|
||||||
created_at: active_vm.created_at,
|
created_at: active_vm.created_at,
|
||||||
@ -884,9 +884,9 @@ pub struct ActiveVmWithNode {
|
|||||||
pub mapped_ports: Vec<(u32, u32)>,
|
pub mapped_ports: Vec<(u32, u32)>,
|
||||||
pub public_ipv4: String,
|
pub public_ipv4: String,
|
||||||
pub public_ipv6: String,
|
pub public_ipv6: String,
|
||||||
pub disk_size_gb: u32,
|
pub disk_gib: u32,
|
||||||
pub vcpus: u32,
|
pub vcpus: u32,
|
||||||
pub memory_mb: u32,
|
pub memory_mib: u32,
|
||||||
pub dtrfs_sha: String,
|
pub dtrfs_sha: String,
|
||||||
pub kernel_sha: String,
|
pub kernel_sha: String,
|
||||||
pub created_at: Datetime,
|
pub created_at: Datetime,
|
||||||
@ -905,9 +905,9 @@ impl From<ActiveVmWithNode> for ActiveVm {
|
|||||||
mapped_ports: val.mapped_ports,
|
mapped_ports: val.mapped_ports,
|
||||||
public_ipv4: val.public_ipv4,
|
public_ipv4: val.public_ipv4,
|
||||||
public_ipv6: val.public_ipv6,
|
public_ipv6: val.public_ipv6,
|
||||||
disk_size_gb: val.disk_size_gb,
|
disk_size_mib: val.disk_gib,
|
||||||
vcpus: val.vcpus,
|
vcpus: val.vcpus,
|
||||||
memory_mb: val.memory_mb,
|
memory_mib: val.memory_mib,
|
||||||
dtrfs_sha: val.dtrfs_sha,
|
dtrfs_sha: val.dtrfs_sha,
|
||||||
kernel_sha: val.kernel_sha,
|
kernel_sha: val.kernel_sha,
|
||||||
created_at: val.created_at,
|
created_at: val.created_at,
|
||||||
@ -974,8 +974,8 @@ impl ActiveVmWithNode {
|
|||||||
// I tried, but this can be done better.
|
// I tried, but this can be done better.
|
||||||
// Storage cost should also be based on tier
|
// Storage cost should also be based on tier
|
||||||
(self.vcpus as u64 * 10)
|
(self.vcpus as u64 * 10)
|
||||||
+ ((self.memory_mb + 256) as u64 / 200)
|
+ ((self.memory_mib + 256) as u64 / 200)
|
||||||
+ (self.disk_size_gb as u64 / 10)
|
+ (self.disk_gib as u64 / 10)
|
||||||
+ (!self.public_ipv4.is_empty() as u64 * 10)
|
+ (!self.public_ipv4.is_empty() as u64 * 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1012,7 +1012,7 @@ impl From<&old_brain::BrainData> for Vec<VmNode> {
|
|||||||
avail_ipv6: old_node.avail_ipv6,
|
avail_ipv6: old_node.avail_ipv6,
|
||||||
avail_ports: old_node.avail_ports,
|
avail_ports: old_node.avail_ports,
|
||||||
max_ports_per_vm: old_node.max_ports_per_vm,
|
max_ports_per_vm: old_node.max_ports_per_vm,
|
||||||
price: old_node.price,
|
price_per_slot: old_node.price,
|
||||||
disconnected_at: Datetime::default(),
|
disconnected_at: Datetime::default(),
|
||||||
connected_at: Datetime::default(),
|
connected_at: Datetime::default(),
|
||||||
});
|
});
|
||||||
@ -1037,9 +1037,9 @@ impl From<&old_brain::BrainData> for Vec<ActiveVm> {
|
|||||||
mapped_ports,
|
mapped_ports,
|
||||||
public_ipv4: old_c.public_ipv4.clone(),
|
public_ipv4: old_c.public_ipv4.clone(),
|
||||||
public_ipv6: old_c.public_ipv6.clone(),
|
public_ipv6: old_c.public_ipv6.clone(),
|
||||||
disk_size_gb: old_c.disk_size_gb,
|
disk_size_mib: old_c.disk_size_gb,
|
||||||
vcpus: old_c.vcpus,
|
vcpus: old_c.vcpus,
|
||||||
memory_mb: old_c.memory_mb,
|
memory_mib: old_c.memory_mb,
|
||||||
dtrfs_sha: old_c.dtrfs_sha.clone(),
|
dtrfs_sha: old_c.dtrfs_sha.clone(),
|
||||||
kernel_sha: old_c.kernel_sha.clone(),
|
kernel_sha: old_c.kernel_sha.clone(),
|
||||||
price_per_unit: old_c.price_per_unit,
|
price_per_unit: old_c.price_per_unit,
|
||||||
|
@ -133,7 +133,7 @@ impl BrainGeneralCli for GeneralCliServer {
|
|||||||
match db::kick_contract(&self.db, &req.operator_wallet, &req.contract_uuid, &req.reason)
|
match db::kick_contract(&self.db, &req.operator_wallet, &req.contract_uuid, &req.reason)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(nano_lp) => Ok(Response::new(KickResp { nano_lp })),
|
Ok(nano_credits) => Ok(Response::new(KickResp { nano_credits })),
|
||||||
Err(e)
|
Err(e)
|
||||||
if matches!(
|
if matches!(
|
||||||
e,
|
e,
|
||||||
|
@ -36,14 +36,14 @@ impl From<NewVmReq> for db::NewVmReq {
|
|||||||
extra_ports: new_vm_req.extra_ports,
|
extra_ports: new_vm_req.extra_ports,
|
||||||
public_ipv4: new_vm_req.public_ipv4,
|
public_ipv4: new_vm_req.public_ipv4,
|
||||||
public_ipv6: new_vm_req.public_ipv6,
|
public_ipv6: new_vm_req.public_ipv6,
|
||||||
disk_size_gb: new_vm_req.disk_size_gb,
|
disk_size_mib: new_vm_req.disk_mib,
|
||||||
vcpus: new_vm_req.vcpus,
|
vcpus: new_vm_req.vcpus,
|
||||||
memory_mb: new_vm_req.memory_mb,
|
memory_mib: new_vm_req.memory_mib,
|
||||||
kernel_url: new_vm_req.kernel_url,
|
kernel_url: new_vm_req.kernel_url,
|
||||||
kernel_sha: new_vm_req.kernel_sha,
|
kernel_sha: new_vm_req.kernel_sha,
|
||||||
dtrfs_url: new_vm_req.dtrfs_url,
|
dtrfs_url: new_vm_req.dtrfs_url,
|
||||||
dtrfs_sha: new_vm_req.dtrfs_sha,
|
dtrfs_sha: new_vm_req.dtrfs_sha,
|
||||||
price_per_unit: new_vm_req.price_per_unit,
|
price_per_slot: new_vm_req.price_per_slot,
|
||||||
locked_nano: new_vm_req.locked_nano,
|
locked_nano: new_vm_req.locked_nano,
|
||||||
created_at: surrealdb::sql::Datetime::default(),
|
created_at: surrealdb::sql::Datetime::default(),
|
||||||
error: String::new(),
|
error: String::new(),
|
||||||
@ -61,42 +61,19 @@ impl From<db::NewVmReq> for NewVmReq {
|
|||||||
extra_ports: new_vm_req.extra_ports,
|
extra_ports: new_vm_req.extra_ports,
|
||||||
public_ipv4: new_vm_req.public_ipv4,
|
public_ipv4: new_vm_req.public_ipv4,
|
||||||
public_ipv6: new_vm_req.public_ipv6,
|
public_ipv6: new_vm_req.public_ipv6,
|
||||||
disk_size_gb: new_vm_req.disk_size_gb,
|
disk_mib: new_vm_req.disk_size_mib,
|
||||||
vcpus: new_vm_req.vcpus,
|
vcpus: new_vm_req.vcpus,
|
||||||
memory_mb: new_vm_req.memory_mb,
|
memory_mib: new_vm_req.memory_mib,
|
||||||
kernel_url: new_vm_req.kernel_url,
|
kernel_url: new_vm_req.kernel_url,
|
||||||
kernel_sha: new_vm_req.kernel_sha,
|
kernel_sha: new_vm_req.kernel_sha,
|
||||||
dtrfs_url: new_vm_req.dtrfs_url,
|
dtrfs_url: new_vm_req.dtrfs_url,
|
||||||
dtrfs_sha: new_vm_req.dtrfs_sha,
|
dtrfs_sha: new_vm_req.dtrfs_sha,
|
||||||
price_per_unit: new_vm_req.price_per_unit,
|
price_per_slot: new_vm_req.price_per_slot,
|
||||||
locked_nano: new_vm_req.locked_nano,
|
locked_nano: new_vm_req.locked_nano,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<db::WrappedMeasurement> for NewVmResp {
|
|
||||||
fn from(resp: db::WrappedMeasurement) -> Self {
|
|
||||||
match resp {
|
|
||||||
db::WrappedMeasurement::Args(uuid, args) => {
|
|
||||||
Self { uuid, error: String::new(), args: Some(args) }
|
|
||||||
}
|
|
||||||
db::WrappedMeasurement::Error(uuid, error) => NewVmResp { uuid, error, args: None },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: NewVmResp is identical to UpdateVmResp so we can actually remove it from proto
|
|
||||||
impl From<db::WrappedMeasurement> for UpdateVmResp {
|
|
||||||
fn from(resp: db::WrappedMeasurement) -> Self {
|
|
||||||
match resp {
|
|
||||||
db::WrappedMeasurement::Args(uuid, args) => {
|
|
||||||
Self { uuid, error: String::new(), args: Some(args) }
|
|
||||||
}
|
|
||||||
db::WrappedMeasurement::Error(uuid, error) => Self { uuid, error, args: None },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<UpdateVmReq> for db::UpdateVmReq {
|
impl From<UpdateVmReq> for db::UpdateVmReq {
|
||||||
fn from(new_vm_req: UpdateVmReq) -> Self {
|
fn from(new_vm_req: UpdateVmReq) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -104,9 +81,9 @@ impl From<UpdateVmReq> for db::UpdateVmReq {
|
|||||||
admin: RecordId::from((ACCOUNT, new_vm_req.admin_pubkey)),
|
admin: RecordId::from((ACCOUNT, new_vm_req.admin_pubkey)),
|
||||||
// vm_node gets modified later, and only if the db::UpdateVmReq is required
|
// vm_node gets modified later, and only if the db::UpdateVmReq is required
|
||||||
vm_node: RecordId::from((VM_NODE, String::new())),
|
vm_node: RecordId::from((VM_NODE, String::new())),
|
||||||
disk_size_gb: new_vm_req.disk_size_gb,
|
disk_mib: new_vm_req.disk_mib,
|
||||||
vcpus: new_vm_req.vcpus,
|
vcpus: new_vm_req.vcpus,
|
||||||
memory_mb: new_vm_req.memory_mb,
|
memory_mib: new_vm_req.memory_mib,
|
||||||
kernel_url: new_vm_req.kernel_url,
|
kernel_url: new_vm_req.kernel_url,
|
||||||
kernel_sha: new_vm_req.kernel_sha,
|
kernel_sha: new_vm_req.kernel_sha,
|
||||||
dtrfs_url: new_vm_req.dtrfs_url,
|
dtrfs_url: new_vm_req.dtrfs_url,
|
||||||
@ -124,9 +101,9 @@ impl From<db::UpdateVmReq> for UpdateVmReq {
|
|||||||
// daemon does not care about VM hostname
|
// daemon does not care about VM hostname
|
||||||
hostname: String::new(),
|
hostname: String::new(),
|
||||||
admin_pubkey: update_vm_req.admin.key().to_string(),
|
admin_pubkey: update_vm_req.admin.key().to_string(),
|
||||||
disk_size_gb: update_vm_req.disk_size_gb,
|
disk_mib: update_vm_req.disk_mib,
|
||||||
vcpus: update_vm_req.vcpus,
|
vcpus: update_vm_req.vcpus,
|
||||||
memory_mb: update_vm_req.memory_mb,
|
memory_mib: update_vm_req.memory_mib,
|
||||||
kernel_url: update_vm_req.kernel_url,
|
kernel_url: update_vm_req.kernel_url,
|
||||||
kernel_sha: update_vm_req.kernel_sha,
|
kernel_sha: update_vm_req.kernel_sha,
|
||||||
dtrfs_url: update_vm_req.dtrfs_url,
|
dtrfs_url: update_vm_req.dtrfs_url,
|
||||||
@ -176,9 +153,9 @@ impl From<db::ActiveVmWithNode> for VmContract {
|
|||||||
"{}, {}, {}",
|
"{}, {}, {}",
|
||||||
db_c.vm_node.city, db_c.vm_node.region, db_c.vm_node.country
|
db_c.vm_node.city, db_c.vm_node.region, db_c.vm_node.country
|
||||||
),
|
),
|
||||||
memory_mb: db_c.memory_mb,
|
memory_mib: db_c.memory_mib,
|
||||||
vcpus: db_c.vcpus,
|
vcpus: db_c.vcpus,
|
||||||
disk_size_gb: db_c.disk_size_gb,
|
disk_mib: db_c.disk_gib,
|
||||||
mapped_ports: db_c
|
mapped_ports: db_c
|
||||||
.mapped_ports
|
.mapped_ports
|
||||||
.iter()
|
.iter()
|
||||||
@ -252,9 +229,9 @@ impl From<db::AppNodeWithReports> for AppNodeListResp {
|
|||||||
impl From<VmNodeResources> for db::VmNodeResources {
|
impl From<VmNodeResources> for db::VmNodeResources {
|
||||||
fn from(res: VmNodeResources) -> Self {
|
fn from(res: VmNodeResources) -> Self {
|
||||||
Self {
|
Self {
|
||||||
avail_mem_mb: res.avail_memory_mb,
|
avail_mem_mib: res.avail_memory_mib,
|
||||||
avail_vcpus: res.avail_vcpus,
|
avail_vcpus: res.avail_vcpus,
|
||||||
avail_storage_gbs: res.avail_storage_gb,
|
avail_storage_mib: res.avail_storage_mib,
|
||||||
avail_ipv4: res.avail_ipv4,
|
avail_ipv4: res.avail_ipv4,
|
||||||
avail_ipv6: res.avail_ipv6,
|
avail_ipv6: res.avail_ipv6,
|
||||||
avail_ports: res.avail_ports,
|
avail_ports: res.avail_ports,
|
||||||
|
@ -50,7 +50,7 @@ impl BrainVmDaemon for VmDaemonServer {
|
|||||||
region: req.region,
|
region: req.region,
|
||||||
city: req.city,
|
city: req.city,
|
||||||
ip: req.main_ip,
|
ip: req.main_ip,
|
||||||
price: req.price,
|
price_per_slot: req.price_per_slot,
|
||||||
avail_mem_mb: 0,
|
avail_mem_mb: 0,
|
||||||
avail_vcpus: 0,
|
avail_vcpus: 0,
|
||||||
avail_storage_gbs: 0,
|
avail_storage_gbs: 0,
|
||||||
@ -165,9 +165,9 @@ impl BrainVmDaemon for VmDaemonServer {
|
|||||||
} else {
|
} else {
|
||||||
db::upsert_record(
|
db::upsert_record(
|
||||||
&self.db,
|
&self.db,
|
||||||
"measurement_args",
|
"new_vm_responses",
|
||||||
&new_vm_resp.uuid,
|
&new_vm_resp.uuid,
|
||||||
new_vm_resp.args.clone(),
|
new_vm_resp.clone(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
if let Some(args) = new_vm_resp.args {
|
if let Some(args) = new_vm_resp.args {
|
||||||
@ -267,6 +267,8 @@ impl BrainVmCli for VmCliServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Maybe get VM data from the database an always inform CLI of real HW details of the VM,
|
||||||
|
// instead of just returning 0 0 0 when nothing changes.
|
||||||
async fn update_vm(&self, req: Request<UpdateVmReq>) -> Result<Response<UpdateVmResp>, Status> {
|
async fn update_vm(&self, req: Request<UpdateVmReq>) -> Result<Response<UpdateVmResp>, Status> {
|
||||||
let req = check_sig_from_req(req)?;
|
let req = check_sig_from_req(req)?;
|
||||||
info!("Update VM requested via CLI: {req:?}");
|
info!("Update VM requested via CLI: {req:?}");
|
||||||
@ -291,6 +293,9 @@ impl BrainVmCli for VmCliServer {
|
|||||||
uuid: req.uuid.clone(),
|
uuid: req.uuid.clone(),
|
||||||
error: "VM Contract does not exist.".to_string(),
|
error: "VM Contract does not exist.".to_string(),
|
||||||
args: None,
|
args: None,
|
||||||
|
vcpus: 0,
|
||||||
|
memory_mib: 0,
|
||||||
|
disk_mib: 0,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
let hw_change_needed = hw_change_submitted.unwrap();
|
let hw_change_needed = hw_change_submitted.unwrap();
|
||||||
@ -300,6 +305,9 @@ impl BrainVmCli for VmCliServer {
|
|||||||
uuid: req.uuid.clone(),
|
uuid: req.uuid.clone(),
|
||||||
error: "No modification required".to_string(),
|
error: "No modification required".to_string(),
|
||||||
args: None,
|
args: None,
|
||||||
|
vcpus: 0,
|
||||||
|
memory_mib: 0,
|
||||||
|
disk_mib: 0,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,6 +317,9 @@ impl BrainVmCli for VmCliServer {
|
|||||||
uuid: req.uuid.clone(),
|
uuid: req.uuid.clone(),
|
||||||
error: String::new(),
|
error: String::new(),
|
||||||
args: None,
|
args: None,
|
||||||
|
vcpus: 0,
|
||||||
|
memory_mib: 0,
|
||||||
|
disk_mib: 0,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@ DEFINE FUNCTION OVERWRITE fn::vm_price_per_minute(
|
|||||||
LET $vm = (select * from $vm_id)[0];
|
LET $vm = (select * from $vm_id)[0];
|
||||||
LET $ip_price = IF $vm.public_ipv4.len() > 0 { 10 } ELSE { 0 };
|
LET $ip_price = IF $vm.public_ipv4.len() > 0 { 10 } ELSE { 0 };
|
||||||
RETURN (
|
RETURN (
|
||||||
($vm.vcpus * 10) + (($vm.memory_mb + 256) / 200) + ($vm.disk_size_gb / 10) + $ip_price)
|
($vm.vcpus * 10) + (($vm.memory_mb + 256) / 200) + ($vm.disk_size_mib / 1024 / 10) + $ip_price)
|
||||||
* $vm.price_per_unit;
|
* ($vm.price_per_slot / 732 / 60);
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE FUNCTION OVERWRITE fn::delete_vm(
|
DEFINE FUNCTION OVERWRITE fn::delete_vm(
|
||||||
|
@ -13,9 +13,9 @@ DEFINE FIELD country ON TABLE vm_node TYPE string;
|
|||||||
DEFINE FIELD region ON TABLE vm_node TYPE string;
|
DEFINE FIELD region ON TABLE vm_node TYPE string;
|
||||||
DEFINE FIELD city ON TABLE vm_node TYPE string;
|
DEFINE FIELD city ON TABLE vm_node TYPE string;
|
||||||
DEFINE FIELD ip ON TABLE vm_node TYPE string;
|
DEFINE FIELD ip ON TABLE vm_node TYPE string;
|
||||||
DEFINE FIELD avail_mem_mb ON TABLE vm_node TYPE int;
|
DEFINE FIELD avail_mem_mib ON TABLE vm_node TYPE int;
|
||||||
DEFINE FIELD avail_vcpus ON TABLE vm_node TYPE int;
|
DEFINE FIELD avail_vcpus ON TABLE vm_node TYPE int;
|
||||||
DEFINE FIELD avail_storage_gbs ON TABLE vm_node TYPE int;
|
DEFINE FIELD avail_storage_mib ON TABLE vm_node TYPE int;
|
||||||
DEFINE FIELD avail_ipv4 ON TABLE vm_node TYPE int;
|
DEFINE FIELD avail_ipv4 ON TABLE vm_node TYPE int;
|
||||||
DEFINE FIELD avail_ipv6 ON TABLE vm_node TYPE int;
|
DEFINE FIELD avail_ipv6 ON TABLE vm_node TYPE int;
|
||||||
DEFINE FIELD avail_ports ON TABLE vm_node TYPE int;
|
DEFINE FIELD avail_ports ON TABLE vm_node TYPE int;
|
||||||
@ -29,15 +29,15 @@ DEFINE FIELD hostname ON TABLE new_vm_req TYPE string;
|
|||||||
DEFINE FIELD extra_ports ON TABLE new_vm_req TYPE array<int>;
|
DEFINE FIELD extra_ports ON TABLE new_vm_req TYPE array<int>;
|
||||||
DEFINE FIELD public_ipv4 ON TABLE new_vm_req TYPE bool;
|
DEFINE FIELD public_ipv4 ON TABLE new_vm_req TYPE bool;
|
||||||
DEFINE FIELD public_ipv6 ON TABLE new_vm_req TYPE bool;
|
DEFINE FIELD public_ipv6 ON TABLE new_vm_req TYPE bool;
|
||||||
DEFINE FIELD disk_size_gb ON TABLE new_vm_req TYPE int;
|
DEFINE FIELD disk_size_mib ON TABLE new_vm_req TYPE int;
|
||||||
DEFINE FIELD vcpus ON TABLE new_vm_req TYPE int;
|
DEFINE FIELD vcpus ON TABLE new_vm_req TYPE int;
|
||||||
DEFINE FIELD memory_mb ON TABLE new_vm_req TYPE int;
|
DEFINE FIELD memory_mib ON TABLE new_vm_req TYPE int;
|
||||||
DEFINE FIELD dtrfs_sha ON TABLE new_vm_req TYPE string;
|
DEFINE FIELD dtrfs_sha ON TABLE new_vm_req TYPE string;
|
||||||
DEFINE FIELD dtrfs_url ON TABLE new_vm_req TYPE string;
|
DEFINE FIELD dtrfs_url ON TABLE new_vm_req TYPE string;
|
||||||
DEFINE FIELD kernel_sha ON TABLE new_vm_req TYPE string;
|
DEFINE FIELD kernel_sha ON TABLE new_vm_req TYPE string;
|
||||||
DEFINE FIELD kernel_url ON TABLE new_vm_req TYPE string;
|
DEFINE FIELD kernel_url ON TABLE new_vm_req TYPE string;
|
||||||
DEFINE FIELD created_at ON TABLE new_vm_req TYPE datetime;
|
DEFINE FIELD created_at ON TABLE new_vm_req TYPE datetime;
|
||||||
DEFINE FIELD price_per_unit ON TABLE new_vm_req TYPE int;
|
DEFINE FIELD pice_per_slot ON TABLE new_vm_req TYPE int;
|
||||||
DEFINE FIELD locked_nano ON TABLE new_vm_req TYPE int;
|
DEFINE FIELD locked_nano ON TABLE new_vm_req TYPE int;
|
||||||
DEFINE FIELD error ON TABLE new_vm_req TYPE string;
|
DEFINE FIELD error ON TABLE new_vm_req TYPE string;
|
||||||
|
|
||||||
@ -46,20 +46,20 @@ DEFINE FIELD hostname ON TABLE active_vm TYPE string;
|
|||||||
DEFINE FIELD mapped_ports ON TABLE active_vm TYPE array<[int, int]>;
|
DEFINE FIELD mapped_ports ON TABLE active_vm TYPE array<[int, int]>;
|
||||||
DEFINE FIELD public_ipv4 ON TABLE active_vm TYPE string;
|
DEFINE FIELD public_ipv4 ON TABLE active_vm TYPE string;
|
||||||
DEFINE FIELD public_ipv6 ON TABLE active_vm TYPE string;
|
DEFINE FIELD public_ipv6 ON TABLE active_vm TYPE string;
|
||||||
DEFINE FIELD disk_size_gb ON TABLE active_vm TYPE int;
|
DEFINE FIELD disk_size_mib ON TABLE active_vm TYPE int;
|
||||||
DEFINE FIELD vcpus ON TABLE active_vm TYPE int;
|
DEFINE FIELD vcpus ON TABLE active_vm TYPE int;
|
||||||
DEFINE FIELD memory_mb ON TABLE active_vm TYPE int;
|
DEFINE FIELD memory_mib ON TABLE active_vm TYPE int;
|
||||||
DEFINE FIELD dtrfs_sha ON TABLE active_vm TYPE string;
|
DEFINE FIELD dtrfs_sha ON TABLE active_vm TYPE string;
|
||||||
DEFINE FIELD kernel_sha ON TABLE active_vm TYPE string;
|
DEFINE FIELD kernel_sha ON TABLE active_vm TYPE string;
|
||||||
DEFINE FIELD created_at ON TABLE active_vm TYPE datetime;
|
DEFINE FIELD created_at ON TABLE active_vm TYPE datetime;
|
||||||
DEFINE FIELD price_per_unit ON TABLE active_vm TYPE int;
|
DEFINE FIELD pice_per_slot ON TABLE active_vm TYPE int;
|
||||||
DEFINE FIELD locked_nano ON TABLE active_vm TYPE int;
|
DEFINE FIELD locked_nano ON TABLE active_vm TYPE int;
|
||||||
DEFINE FIELD collected_at ON TABLE active_vm TYPE datetime;
|
DEFINE FIELD collected_at ON TABLE active_vm TYPE datetime;
|
||||||
|
|
||||||
DEFINE TABLE update_vm_req TYPE RELATION FROM account TO vm_node SCHEMAFULL;
|
DEFINE TABLE update_vm_req TYPE RELATION FROM account TO vm_node SCHEMAFULL;
|
||||||
DEFINE FIELD vcpus ON TABLE update_vm_req TYPE int;
|
DEFINE FIELD vcpus ON TABLE update_vm_req TYPE int;
|
||||||
DEFINE FIELD memory_mb ON TABLE update_vm_req TYPE int;
|
DEFINE FIELD memory_mib ON TABLE update_vm_req TYPE int;
|
||||||
DEFINE FIELD disk_size_gb ON TABLE update_vm_req TYPE int;
|
DEFINE FIELD disk_size_mib ON TABLE update_vm_req TYPE int;
|
||||||
DEFINE FIELD dtrfs_sha ON TABLE update_vm_req TYPE string;
|
DEFINE FIELD dtrfs_sha ON TABLE update_vm_req TYPE string;
|
||||||
DEFINE FIELD dtrfs_url ON TABLE update_vm_req TYPE string;
|
DEFINE FIELD dtrfs_url ON TABLE update_vm_req TYPE string;
|
||||||
DEFINE FIELD kernel_sha ON TABLE update_vm_req TYPE string;
|
DEFINE FIELD kernel_sha ON TABLE update_vm_req TYPE string;
|
||||||
@ -72,14 +72,14 @@ DEFINE FIELD hostname ON TABLE deleted_vm TYPE string;
|
|||||||
DEFINE FIELD mapped_ports ON TABLE deleted_vm TYPE array<[int, int]>;
|
DEFINE FIELD mapped_ports ON TABLE deleted_vm TYPE array<[int, int]>;
|
||||||
DEFINE FIELD public_ipv4 ON TABLE deleted_vm TYPE string;
|
DEFINE FIELD public_ipv4 ON TABLE deleted_vm TYPE string;
|
||||||
DEFINE FIELD public_ipv6 ON TABLE deleted_vm TYPE string;
|
DEFINE FIELD public_ipv6 ON TABLE deleted_vm TYPE string;
|
||||||
DEFINE FIELD disk_size_gb ON TABLE deleted_vm TYPE int;
|
DEFINE FIELD disk_size_mib ON TABLE deleted_vm TYPE int;
|
||||||
DEFINE FIELD vcpus ON TABLE deleted_vm TYPE int;
|
DEFINE FIELD vcpus ON TABLE deleted_vm TYPE int;
|
||||||
DEFINE FIELD memory_mb ON TABLE deleted_vm TYPE int;
|
DEFINE FIELD memory_mib ON TABLE deleted_vm TYPE int;
|
||||||
DEFINE FIELD dtrfs_sha ON TABLE deleted_vm TYPE string;
|
DEFINE FIELD dtrfs_sha ON TABLE deleted_vm TYPE string;
|
||||||
DEFINE FIELD kernel_sha ON TABLE deleted_vm TYPE string;
|
DEFINE FIELD kernel_sha ON TABLE deleted_vm TYPE string;
|
||||||
DEFINE FIELD created_at ON TABLE deleted_vm TYPE datetime;
|
DEFINE FIELD created_at ON TABLE deleted_vm TYPE datetime;
|
||||||
DEFINE FIELD deleted_at ON TABLE deleted_vm TYPE datetime DEFAULT time::now();
|
DEFINE FIELD deleted_at ON TABLE deleted_vm TYPE datetime DEFAULT time::now();
|
||||||
DEFINE FIELD price_per_unit ON TABLE deleted_vm TYPE int;
|
DEFINE FIELD pice_per_slot ON TABLE deleted_vm TYPE int;
|
||||||
|
|
||||||
DEFINE TABLE app_node SCHEMAFULL;
|
DEFINE TABLE app_node SCHEMAFULL;
|
||||||
DEFINE FIELD operator ON TABLE app_node TYPE record<account>;
|
DEFINE FIELD operator ON TABLE app_node TYPE record<account>;
|
||||||
|
@ -105,14 +105,14 @@ INSERT RELATION {
|
|||||||
out: vm_node:online_node,
|
out: vm_node:online_node,
|
||||||
collected_at: time::now() - 1h,
|
collected_at: time::now() - 1h,
|
||||||
created_at: time::now() - 1h,
|
created_at: time::now() - 1h,
|
||||||
disk_size_gb: 400,
|
disk_size_mib: 400 * 1024,
|
||||||
dtrfs_sha: 'd207644ee60d54009b6ecdfb720e2ec251cde31774dd249fcc7435aca0377990',
|
dtrfs_sha: 'd207644ee60d54009b6ecdfb720e2ec251cde31774dd249fcc7435aca0377990',
|
||||||
hostname: 'vm1',
|
hostname: 'vm1',
|
||||||
kernel_sha: 'e765e56166ef321b53399b9638584d1279821dbe3d46191c1f66bbaa075e7919',
|
kernel_sha: 'e765e56166ef321b53399b9638584d1279821dbe3d46191c1f66bbaa075e7919',
|
||||||
locked_nano: 1_000_000_000,
|
locked_nano: 1_000_000_000,
|
||||||
mapped_ports: [],
|
mapped_ports: [],
|
||||||
memory_mb: 80000,
|
memory_mb: 80000,
|
||||||
price_per_unit: 20000,
|
price_per_slot: 4500000000,
|
||||||
public_ipv4: '192.168.10.10',
|
public_ipv4: '192.168.10.10',
|
||||||
public_ipv6: '',
|
public_ipv6: '',
|
||||||
vcpus: 40
|
vcpus: 40
|
||||||
@ -124,7 +124,7 @@ INSERT RELATION {
|
|||||||
out: vm_node:offline_node,
|
out: vm_node:offline_node,
|
||||||
collected_at: time::now() - 10m,
|
collected_at: time::now() - 10m,
|
||||||
created_at: time::now() - 1h,
|
created_at: time::now() - 1h,
|
||||||
disk_size_gb: 10,
|
disk_size_mib: 10 * 1024,
|
||||||
dtrfs_sha: 'd207644ee60d54009b6ecdfb720e2ec251cde31774dd249fcc7435aca0377990',
|
dtrfs_sha: 'd207644ee60d54009b6ecdfb720e2ec251cde31774dd249fcc7435aca0377990',
|
||||||
hostname: 'vm1',
|
hostname: 'vm1',
|
||||||
kernel_sha: 'e765e56166ef321b53399b9638584d1279821dbe3d46191c1f66bbaa075e7919',
|
kernel_sha: 'e765e56166ef321b53399b9638584d1279821dbe3d46191c1f66bbaa075e7919',
|
||||||
@ -136,7 +136,7 @@ INSERT RELATION {
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
memory_mb: 5000,
|
memory_mb: 5000,
|
||||||
price_per_unit: 20000,
|
price_per_slot: 4500000000,
|
||||||
public_ipv4: '',
|
public_ipv4: '',
|
||||||
public_ipv6: '',
|
public_ipv6: '',
|
||||||
vcpus: 4
|
vcpus: 4
|
||||||
@ -148,14 +148,14 @@ INSERT RELATION {
|
|||||||
out: vm_node:online_node2,
|
out: vm_node:online_node2,
|
||||||
collected_at: time::now() - 30d,
|
collected_at: time::now() - 30d,
|
||||||
created_at: time::now() - 60d,
|
created_at: time::now() - 60d,
|
||||||
disk_size_gb: 10,
|
disk_size_mib: 10 * 1024,
|
||||||
dtrfs_sha: 'd207644ee60d54009b6ecdfb720e2ec251cde31774dd249fcc7435aca0377990',
|
dtrfs_sha: 'd207644ee60d54009b6ecdfb720e2ec251cde31774dd249fcc7435aca0377990',
|
||||||
hostname: 'vm1',
|
hostname: 'vm1',
|
||||||
kernel_sha: 'e765e56166ef321b53399b9638584d1279821dbe3d46191c1f66bbaa075e7919',
|
kernel_sha: 'e765e56166ef321b53399b9638584d1279821dbe3d46191c1f66bbaa075e7919',
|
||||||
locked_nano: 25_000_000_000,
|
locked_nano: 25_000_000_000,
|
||||||
mapped_ports: [],
|
mapped_ports: [],
|
||||||
memory_mb: 1000,
|
memory_mb: 1000,
|
||||||
price_per_unit: 20000,
|
price_per_slot: 4500000000,
|
||||||
public_ipv4: '192.168.10.20',
|
public_ipv4: '192.168.10.20',
|
||||||
public_ipv6: '',
|
public_ipv6: '',
|
||||||
vcpus: 1
|
vcpus: 1
|
||||||
|
Loading…
Reference in New Issue
Block a user