445 lines
13 KiB
V
445 lines
13 KiB
V
module models_tfgrid
|
|
|
|
import freeflowuniverse.herolib.data.encoder
|
|
import freeflowuniverse.herolib.data.ourtime
|
|
import freeflowuniverse.herolib.hero.db
|
|
|
|
// Storage device information
|
|
pub struct StorageDevice {
|
|
pub mut:
|
|
id string // can be used in node
|
|
size_gb f64 // Size of the storage device in gigabytes
|
|
description string // Description of the storage device
|
|
}
|
|
|
|
// Memory device information
|
|
pub struct MemoryDevice {
|
|
pub mut:
|
|
id string // can be used in node
|
|
size_gb f64 // Size of the memory device in gigabytes
|
|
description string // Description of the memory device
|
|
}
|
|
|
|
// CPU device information
|
|
pub struct CPUDevice {
|
|
pub mut:
|
|
id string // can be used in node
|
|
cores int // Number of CPU cores
|
|
passmark int
|
|
description string // Description of the CPU
|
|
cpu_brand string // Brand of the CPU
|
|
cpu_version string // Version of the CPU
|
|
}
|
|
|
|
// GPU device information
|
|
pub struct GPUDevice {
|
|
pub mut:
|
|
id string // can be used in node
|
|
cores int // Number of GPU cores
|
|
memory_gb f64 // Size of the GPU memory in gigabytes
|
|
description string // Description of the GPU
|
|
gpu_brand string
|
|
gpu_version string
|
|
}
|
|
|
|
// Network device information
|
|
pub struct NetworkDevice {
|
|
pub mut:
|
|
id string // can be used in node
|
|
speed_mbps int // Network speed in Mbps
|
|
description string // Description of the network device
|
|
}
|
|
|
|
// Aggregated device info for a node
|
|
pub struct DeviceInfo {
|
|
pub mut:
|
|
vendor string
|
|
storage []StorageDevice
|
|
memory []MemoryDevice
|
|
cpu []CPUDevice
|
|
gpu []GPUDevice
|
|
network []NetworkDevice
|
|
}
|
|
|
|
// NodeCapacity represents the hardware capacity details of a node
|
|
pub struct NodeCapacity {
|
|
pub mut:
|
|
storage_gb f64 // Total storage in gigabytes
|
|
mem_gb f64 // Total memory in gigabytes
|
|
mem_gb_gpu f64 // Total GPU memory in gigabytes
|
|
passmark int // Passmark score for the node
|
|
vcores int // Total virtual cores
|
|
}
|
|
|
|
// Pricing policy for slices
|
|
pub struct PricingPolicy {
|
|
pub mut:
|
|
name string // Human friendly policy name (e.g. "fixed", "market")
|
|
details string // Optional free-form details as JSON-encoded string
|
|
marketplace_year_discounts []int // e.g. [30, 40, 50] means if user has more CC than 1Y utilization, 30% discount, etc.
|
|
}
|
|
|
|
// SLA policy for slices
|
|
pub struct SLAPolicy {
|
|
pub mut:
|
|
uptime f32 // Uptime in percentage (0..100)
|
|
max_response_time_ms u32 // Max response time in ms
|
|
sla_bandwidth_mbit int // minimal mbits we can expect avg over 1h per node, 0 means we don't guarantee
|
|
sla_penalty int // 0-100, percent of money given back in relation to month if sla breached
|
|
}
|
|
|
|
// Compute slice (typically represents a base unit of compute)
|
|
pub struct ComputeSlice {
|
|
pub mut:
|
|
id int // the id of the slice in the node
|
|
mem_gb f64
|
|
storage_gb f64
|
|
passmark int
|
|
vcores int
|
|
cpu_oversubscription int
|
|
storage_oversubscription int
|
|
price_range []f64 // Min/max allowed price range for validation
|
|
gpus u8 // nr of GPU's see node to know what GPU's are
|
|
price_cc f64 // price per slice in cloud credits
|
|
pricing_policy PricingPolicy
|
|
sla_policy SLAPolicy
|
|
}
|
|
|
|
// Storage slice (typically 1GB of storage)
|
|
pub struct StorageSlice {
|
|
pub mut:
|
|
id int // the id of the slice in the node
|
|
price_cc f64 // price per slice in cloud credits
|
|
pricing_policy PricingPolicy
|
|
sla_policy SLAPolicy
|
|
}
|
|
|
|
// Grid4 Node model - ROOT OBJECT
|
|
@[heap]
|
|
pub struct Node {
|
|
db.Base
|
|
pub mut:
|
|
nodegroupid int // Link to node group
|
|
uptime int // Uptime percentage 0..100
|
|
computeslices []ComputeSlice
|
|
storageslices []StorageSlice
|
|
devices DeviceInfo
|
|
country string // 2 letter code
|
|
capacity NodeCapacity // Hardware capacity details
|
|
birthtime u32 // first time node was active
|
|
pubkey string
|
|
signature_node string // signature done on node to validate pubkey with privkey
|
|
signature_farmer string // signature as done by farmers to validate their identity
|
|
}
|
|
|
|
pub struct DBNode {
|
|
pub mut:
|
|
db &db.DB @[skip; str: skip]
|
|
}
|
|
|
|
pub fn (self Node) type_name() string {
|
|
return 'node'
|
|
}
|
|
|
|
pub fn (self Node) description(methodname string) string {
|
|
match methodname {
|
|
'set' {
|
|
return 'Create or update a node. Returns the ID of the node.'
|
|
}
|
|
'get' {
|
|
return 'Retrieve a node by ID. Returns the node object.'
|
|
}
|
|
'delete' {
|
|
return 'Delete a node by ID. Returns true if successful.'
|
|
}
|
|
'exist' {
|
|
return 'Check if a node exists by ID. Returns true or false.'
|
|
}
|
|
'list' {
|
|
return 'List all nodes. Returns an array of node objects.'
|
|
}
|
|
else {
|
|
return 'Node management methods for Grid4 infrastructure.'
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn (self Node) example(methodname string) (string, string) {
|
|
match methodname {
|
|
'set' {
|
|
return '{"node": {"name": "node-001", "nodegroupid": 1, "uptime": 99, "country": "BE", "devices": {"vendor": "Dell"}, "capacity": {"storage_gb": 1000, "mem_gb": 64, "vcores": 16, "passmark": 15000}}}', '1'
|
|
}
|
|
'get' {
|
|
return '{"id": 1}', '{"name": "node-001", "nodegroupid": 1, "uptime": 99, "country": "BE"}'
|
|
}
|
|
'delete' {
|
|
return '{"id": 1}', 'true'
|
|
}
|
|
'exist' {
|
|
return '{"id": 1}', 'true'
|
|
}
|
|
'list' {
|
|
return '{}', '[{"name": "node-001", "nodegroupid": 1, "uptime": 99, "country": "BE"}]'
|
|
}
|
|
else {
|
|
return '{}', '{}'
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn (self Node) dump(mut e encoder.Encoder) ! {
|
|
e.add_int(self.nodegroupid)
|
|
e.add_int(self.uptime)
|
|
|
|
// Encode compute slices
|
|
e.add_int(self.computeslices.len)
|
|
for slice in self.computeslices {
|
|
e.add_int(slice.id)
|
|
e.add_f64(slice.mem_gb)
|
|
e.add_f64(slice.storage_gb)
|
|
e.add_int(slice.passmark)
|
|
e.add_int(slice.vcores)
|
|
e.add_int(slice.cpu_oversubscription)
|
|
e.add_int(slice.storage_oversubscription)
|
|
e.add_list_f64(slice.price_range)
|
|
e.add_u8(slice.gpus)
|
|
e.add_f64(slice.price_cc)
|
|
e.add_string(slice.pricing_policy.name)
|
|
e.add_string(slice.pricing_policy.details)
|
|
e.add_list_int(slice.pricing_policy.marketplace_year_discounts)
|
|
e.add_f32(slice.sla_policy.uptime)
|
|
e.add_u32(slice.sla_policy.max_response_time_ms)
|
|
e.add_int(slice.sla_policy.sla_bandwidth_mbit)
|
|
e.add_int(slice.sla_policy.sla_penalty)
|
|
}
|
|
|
|
// Encode storage slices
|
|
e.add_int(self.storageslices.len)
|
|
for slice in self.storageslices {
|
|
e.add_int(slice.id)
|
|
e.add_f64(slice.price_cc)
|
|
e.add_string(slice.pricing_policy.name)
|
|
e.add_string(slice.pricing_policy.details)
|
|
e.add_list_int(slice.pricing_policy.marketplace_year_discounts)
|
|
e.add_f32(slice.sla_policy.uptime)
|
|
e.add_u32(slice.sla_policy.max_response_time_ms)
|
|
e.add_int(slice.sla_policy.sla_bandwidth_mbit)
|
|
e.add_int(slice.sla_policy.sla_penalty)
|
|
}
|
|
|
|
// Encode devices
|
|
e.add_string(self.devices.vendor)
|
|
e.add_int(self.devices.storage.len)
|
|
for device in self.devices.storage {
|
|
e.add_string(device.id)
|
|
e.add_f64(device.size_gb)
|
|
e.add_string(device.description)
|
|
}
|
|
e.add_int(self.devices.memory.len)
|
|
for device in self.devices.memory {
|
|
e.add_string(device.id)
|
|
e.add_f64(device.size_gb)
|
|
e.add_string(device.description)
|
|
}
|
|
e.add_int(self.devices.cpu.len)
|
|
for device in self.devices.cpu {
|
|
e.add_string(device.id)
|
|
e.add_int(device.cores)
|
|
e.add_int(device.passmark)
|
|
e.add_string(device.description)
|
|
e.add_string(device.cpu_brand)
|
|
e.add_string(device.cpu_version)
|
|
}
|
|
e.add_int(self.devices.gpu.len)
|
|
for device in self.devices.gpu {
|
|
e.add_string(device.id)
|
|
e.add_int(device.cores)
|
|
e.add_f64(device.memory_gb)
|
|
e.add_string(device.description)
|
|
e.add_string(device.gpu_brand)
|
|
e.add_string(device.gpu_version)
|
|
}
|
|
e.add_int(self.devices.network.len)
|
|
for device in self.devices.network {
|
|
e.add_string(device.id)
|
|
e.add_int(device.speed_mbps)
|
|
e.add_string(device.description)
|
|
}
|
|
|
|
e.add_string(self.country)
|
|
e.add_f64(self.capacity.storage_gb)
|
|
e.add_f64(self.capacity.mem_gb)
|
|
e.add_f64(self.capacity.mem_gb_gpu)
|
|
e.add_int(self.capacity.passmark)
|
|
e.add_int(self.capacity.vcores)
|
|
e.add_u32(self.birthtime)
|
|
e.add_string(self.pubkey)
|
|
e.add_string(self.signature_node)
|
|
e.add_string(self.signature_farmer)
|
|
}
|
|
|
|
fn (mut self DBNode) load(mut o Node, mut e encoder.Decoder) ! {
|
|
o.nodegroupid = e.get_int()!
|
|
o.uptime = e.get_int()!
|
|
|
|
// Decode compute slices
|
|
compute_slices_len := e.get_int()!
|
|
o.computeslices = []ComputeSlice{len: compute_slices_len}
|
|
for i in 0 .. compute_slices_len {
|
|
o.computeslices[i].id = e.get_int()!
|
|
o.computeslices[i].mem_gb = e.get_f64()!
|
|
o.computeslices[i].storage_gb = e.get_f64()!
|
|
o.computeslices[i].passmark = e.get_int()!
|
|
o.computeslices[i].vcores = e.get_int()!
|
|
o.computeslices[i].cpu_oversubscription = e.get_int()!
|
|
o.computeslices[i].storage_oversubscription = e.get_int()!
|
|
o.computeslices[i].price_range = e.get_list_f64()!
|
|
o.computeslices[i].gpus = e.get_u8()!
|
|
o.computeslices[i].price_cc = e.get_f64()!
|
|
o.computeslices[i].pricing_policy.name = e.get_string()!
|
|
o.computeslices[i].pricing_policy.details = e.get_string()!
|
|
o.computeslices[i].pricing_policy.marketplace_year_discounts = e.get_list_int()!
|
|
o.computeslices[i].sla_policy.uptime = e.get_f32()!
|
|
o.computeslices[i].sla_policy.max_response_time_ms = e.get_u32()!
|
|
o.computeslices[i].sla_policy.sla_bandwidth_mbit = e.get_int()!
|
|
o.computeslices[i].sla_policy.sla_penalty = e.get_int()!
|
|
}
|
|
|
|
// Decode storage slices
|
|
storage_slices_len := e.get_int()!
|
|
o.storageslices = []StorageSlice{len: storage_slices_len}
|
|
for i in 0 .. storage_slices_len {
|
|
o.storageslices[i].id = e.get_int()!
|
|
o.storageslices[i].price_cc = e.get_f64()!
|
|
o.storageslices[i].pricing_policy.name = e.get_string()!
|
|
o.storageslices[i].pricing_policy.details = e.get_string()!
|
|
o.storageslices[i].pricing_policy.marketplace_year_discounts = e.get_list_int()!
|
|
o.storageslices[i].sla_policy.uptime = e.get_f32()!
|
|
o.storageslices[i].sla_policy.max_response_time_ms = e.get_u32()!
|
|
o.storageslices[i].sla_policy.sla_bandwidth_mbit = e.get_int()!
|
|
o.storageslices[i].sla_policy.sla_penalty = e.get_int()!
|
|
}
|
|
|
|
// Decode devices
|
|
o.devices.vendor = e.get_string()!
|
|
|
|
storage_devices_len := e.get_int()!
|
|
o.devices.storage = []StorageDevice{len: storage_devices_len}
|
|
for i in 0 .. storage_devices_len {
|
|
o.devices.storage[i].id = e.get_string()!
|
|
o.devices.storage[i].size_gb = e.get_f64()!
|
|
o.devices.storage[i].description = e.get_string()!
|
|
}
|
|
|
|
memory_devices_len := e.get_int()!
|
|
o.devices.memory = []MemoryDevice{len: memory_devices_len}
|
|
for i in 0 .. memory_devices_len {
|
|
o.devices.memory[i].id = e.get_string()!
|
|
o.devices.memory[i].size_gb = e.get_f64()!
|
|
o.devices.memory[i].description = e.get_string()!
|
|
}
|
|
|
|
cpu_devices_len := e.get_int()!
|
|
o.devices.cpu = []CPUDevice{len: cpu_devices_len}
|
|
for i in 0 .. cpu_devices_len {
|
|
o.devices.cpu[i].id = e.get_string()!
|
|
o.devices.cpu[i].cores = e.get_int()!
|
|
o.devices.cpu[i].passmark = e.get_int()!
|
|
o.devices.cpu[i].description = e.get_string()!
|
|
o.devices.cpu[i].cpu_brand = e.get_string()!
|
|
o.devices.cpu[i].cpu_version = e.get_string()!
|
|
}
|
|
|
|
gpu_devices_len := e.get_int()!
|
|
o.devices.gpu = []GPUDevice{len: gpu_devices_len}
|
|
for i in 0 .. gpu_devices_len {
|
|
o.devices.gpu[i].id = e.get_string()!
|
|
o.devices.gpu[i].cores = e.get_int()!
|
|
o.devices.gpu[i].memory_gb = e.get_f64()!
|
|
o.devices.gpu[i].description = e.get_string()!
|
|
o.devices.gpu[i].gpu_brand = e.get_string()!
|
|
o.devices.gpu[i].gpu_version = e.get_string()!
|
|
}
|
|
|
|
network_devices_len := e.get_int()!
|
|
o.devices.network = []NetworkDevice{len: network_devices_len}
|
|
for i in 0 .. network_devices_len {
|
|
o.devices.network[i].id = e.get_string()!
|
|
o.devices.network[i].speed_mbps = e.get_int()!
|
|
o.devices.network[i].description = e.get_string()!
|
|
}
|
|
|
|
o.country = e.get_string()!
|
|
o.capacity.storage_gb = e.get_f64()!
|
|
o.capacity.mem_gb = e.get_f64()!
|
|
o.capacity.mem_gb_gpu = e.get_f64()!
|
|
o.capacity.passmark = e.get_int()!
|
|
o.capacity.vcores = e.get_int()!
|
|
o.birthtime = e.get_u32()!
|
|
o.pubkey = e.get_string()!
|
|
o.signature_node = e.get_string()!
|
|
o.signature_farmer = e.get_string()!
|
|
}
|
|
|
|
@[params]
|
|
pub struct NodeArg {
|
|
pub mut:
|
|
name string
|
|
description string
|
|
nodegroupid int
|
|
uptime int
|
|
computeslices []ComputeSlice
|
|
storageslices []StorageSlice
|
|
devices DeviceInfo
|
|
country string
|
|
capacity NodeCapacity
|
|
birthtime u32
|
|
pubkey string
|
|
signature_node string
|
|
signature_farmer string
|
|
}
|
|
|
|
pub fn (mut self DBNode) new(args NodeArg) !Node {
|
|
mut o := Node{
|
|
nodegroupid: args.nodegroupid
|
|
uptime: args.uptime
|
|
computeslices: args.computeslices
|
|
storageslices: args.storageslices
|
|
devices: args.devices
|
|
country: args.country
|
|
capacity: args.capacity
|
|
birthtime: args.birthtime
|
|
pubkey: args.pubkey
|
|
signature_node: args.signature_node
|
|
signature_farmer: args.signature_farmer
|
|
}
|
|
|
|
o.name = args.name
|
|
o.description = args.description
|
|
o.updated_at = ourtime.now().unix()
|
|
|
|
return o
|
|
}
|
|
|
|
pub fn (mut self DBNode) set(o Node) !Node {
|
|
return self.db.set[Node](o)!
|
|
}
|
|
|
|
pub fn (mut self DBNode) delete(id u32) ! {
|
|
self.db.delete[Node](id)!
|
|
}
|
|
|
|
pub fn (mut self DBNode) exist(id u32) !bool {
|
|
return self.db.exists[Node](id)!
|
|
}
|
|
|
|
pub fn (mut self DBNode) get(id u32) !Node {
|
|
mut o, data := self.db.get_data[Node](id)!
|
|
mut e_decoder := encoder.decoder_new(data)
|
|
self.load(mut o, mut e_decoder)!
|
|
return o
|
|
}
|
|
|
|
pub fn (mut self DBNode) list() ![]Node {
|
|
return self.db.list[Node]()!.map(self.get(it)!)
|
|
} |