work on api objects

if only the api was better
This commit is contained in:
Minecon724 2024-07-30 17:39:35 +02:00
parent bc25923883
commit 09f727c643
Signed by: Minecon724
GPG key ID: 3CCC4D267742C8E8
7 changed files with 212 additions and 119 deletions

View file

@ -1,17 +1,21 @@
package eu.m724.vastapp.vastai
class Utils {
class StorageCapacityConverters {
companion object {
fun mbToMib(mb: Number): Double {
return mb.toDouble() * 1.048576
}
fun mibToMb(mib: Number): Double {
return mib.toDouble() / 1.048576
}
fun gbToGib(gb: Number): Double {
return gb.toDouble() * 1.073741824
}
fun mibToMb(mib: Number): Double {
return mib.toDouble() / 1.073741824
fun gibToGb(gib: Number): Double {
return gib.toDouble() / 1.073741824
}
}
}

View file

@ -7,15 +7,15 @@ import org.json.JSONObject
* units are in decimal bytes that is 1000 MB GB
*/
data class Instance(
val id: Int,
val machine: Machine,
val pricing: Pricing,
/** memory available in instance in MB */
val instanceMemoryMb: Int,
/** cpu cores available in instance like 6.1 */
/** memory assigned to the instance in MB */
val instanceMemory: Int,
/** cpu cores assigned to the instance like 6.1 */
val instanceCpuCores: Double,
/** how many (same) gpus the instance has*/
val instanceNumGpus: Int,
/** gpus assigned to the instance */
val instanceGpus: Int,
/** "Deep Learning Performance", it's very specific like 15.679831880208411 */
val dlPerf: Double,
@ -24,29 +24,19 @@ data class Instance(
* at least I think because it's recent and unavailable machines don't have that */
val startDate: Long,
/** when instance will expire as unix seconds, like 1861891577 */
val endDate: Long,
/** is the instance available for rental */
val available: Boolean
val endDate: Long
) {
companion object {
fun fromJson(json: JSONObject): Instance {
return Instance(
json.getInt("id"),
Machine.fromJson(json),
json.getInt("cpu_ram"),
Pricing.fromJson(json),
(json.getInt("cpu_ram") / json.getDouble("gpu_frac")).toInt(),
json.getDouble("cpu_cores_effective"),
json.getInt("num_gpus"),
json.getDouble("dlperf"),
json.getDouble("dph_base"),
json.getDouble("storage_cost"),
json.getDouble("inet_down_cost"),
json.getDouble("inet_up_cost"),
json.getBoolean("is_bid"),
json.getDouble("min_bid"),
json.getDouble("start_date").toLong(),
json.getLong("end_date"),
json.getBoolean("rentable")
json.getDouble("end_date").toLong()
)
}
}

View file

@ -1,6 +1,6 @@
package eu.m724.vastapp.vastai.data
import eu.m724.vastapp.vastai.Utils
import eu.m724.vastapp.vastai.StorageCapacityConverters
import org.json.JSONObject
/**
@ -8,69 +8,23 @@ import org.json.JSONObject
* that is the machine with physical resources
*/
data class Machine(
val id: Int,
val machineId: Int,
/** machine host's id, that is the account the machine is listed by */
val hostId: Int,
val cpu: CPU,
val gpu: GPU,
val disk: Disk,
val network: Network,
/** motherboard name, like X99 or TUF GAMING X570 */
val motherboardName: String,
/** machine ram in MB */
val memory: Double,
/** cpu architecture, like amd64 */
val cpuArch: String,
/** machine cpu cores like 12 */
val cpuCores: Int,
/** readable cpu name like xeon something */
val cpuName: String,
/** only when viewing a not rented instance */
val cpuGhz: Double,
/** disk bandwidth in MB/s (TODO find out) like 1225.1 */
val diskBandwidth: Double,
/** disk name, like nvme (literally) or a model like SPCC M.2 PCIe SSD */
val diskName: String,
/** available disk space on host in GB (TODO find out) like 95.833336 */
val diskSpace: Double,
/** pcie gpu lanes like 8 */
val gpuLanes: Int,
/** vram bandwidth in GB/s (TODO find out) like 3518 */
val gpuMemoryBandwidth: Double,
/** gpu name like RTX 4090 */
val gpuName: String,
/** vram in MB */
val gpuMemoryMb: Int,
/** max cuda version like 12.2 */
val cudaMaxGood: Double,
/** nvidia driver version like 545.23.06 */
val driverVersion: String,
/** not sure, changes with gpu series, like 860 for rtx 3000 series*/
val computeCap: Int,
/** pcie version like 3.0 or 4.0 */
val pcieGen: Double,
/** pcie bandwidth in GB/s (TODO find out) like 11.7 */
val pcieBandwidth: Double,
/** download speed in Mbps */
val inetDownSpeedMbps: Double,
/** upload speed in Mbps */
val inetUpSpeedMbps: Double,
/** amount of open ports like 99 */
val directPortCount: Int,
/** public ip address of the machine, like 192.0.2.1 */
val publicAddress: String,
/** self explanatory but not sure if matters */
val isStaticAddress: Boolean,
/** formatted as City, CC like Quebec, CA */
val geolocation: String,
val memory: Int,
/** reliability of the machine 0-1 */
val reliability: Double,
/** how is the machine hosted, 0 normal, 1 datacenter */
val hostingType: Int,
val hostingClass: HostingClass,
val verification: MachineVerification
) {
companion object {
@ -78,38 +32,110 @@ data class Machine(
return Machine(
json.getInt("machine_id"),
json.getInt("host_id"),
CPU(
json.getString("cpu_name"),
json.getString("cpu_arch"),
json.getInt("cpu_cores"),
(json.opt("cpu_ghz") ?: null) as Double?,
),
GPU(
json.getString("gpu_name"),
json.getDouble("total_flops"),
StorageCapacityConverters.mibToMb(json.getInt("gpu_ram")).toInt(),
json.getDouble("gpu_mem_bw"),
json.getInt("gpu_lanes"),
json.getDouble("pci_gen"),
json.getDouble("pcie_bw"),
json.getDouble("cuda_max_good"),
json.getString("driver_version"),
json.getInt("compute_cap")
),
Disk(
json.getString("disk_name"),
json.getDouble("disk_bw")
),
Network(
json.getDouble("inet_down"),
json.getDouble("inet_up"),
json.getInt("direct_port_count"),
json.getString("public_ipaddr"),
json.getBoolean("static_ip"),
json.getString("geolocation")
),
json.getString("mobo_name"),
json.getInt("cpu_ram") / json.getDouble("gpu_frac"),
json.getString("cpu_arch"),
json.getInt("cpu_cores"),
json.getString("cpu_name"),
json.optDouble("cpu_ghz", -1.0),
json.getDouble("disk_bw"),
json.getString("disk_name"),
json.getDouble("disk_space"),
json.getInt("gpu_lanes"),
json.getDouble("gpu_mem_bw"),
json.getString("gpu_name"),
Utils.mibToMb(json.getInt("gpu_ram")).toInt(),
json.getDouble("cuda_max_good"),
json.getString("driver_version"),
json.getInt("compute_cap"),
json.getDouble("pci_gen"),
json.getDouble("pcie_bw"),
json.getDouble("inet_down"),
json.getDouble("inet_up"),
json.getInt("direct_port_count"),
json.getString("public_ipaddr"),
json.getBoolean("static_ip"),
json.getString("geolocation"),
json.getInt("cpu_ram"),
json.getDouble("reliability2"),
json.getInt("hostingType"),
HostingClass.entries.getOrElse(json.getInt("hostingType")) { HostingClass.PRIVATE },
MachineVerification.fromString(json.getString("verification"))
)
}
}
}
data class CPU(
/** readable cpu model name like xeon something */
val model: String,
/** cpu architecture, like amd64 */
val architecture: String,
/** machine cpu cores like 12 */
val cores: Int,
/** cpu frequency in GHz
* null if viewing a rented instance */
val frequency: Double?
)
data class Disk(
/** disk label, like nvme (literally) or a model like SPCC M.2 PCIe SSD */
val model: String,
/** disk "bandwidth" in MB/s (TODO find out mb or mib?)
* bandwidth is the maximum capacity of the channel, while speed is the actual rate at which data is being transferred
* - llama */
val diskSpeed: Double
)
data class Network(
/** download speed in Mbps */
val downloadSpeed: Double,
/** upload speed in Mbps */
val uploadSpeed: Double,
/** how many forwarded ports */
val portCount: Int,
/** public ip address for inbound connections */
val publicAddress: String,
val isAddressStatic: Boolean,
/** formatted as City, CC like Quebec, CA */
val geolocation: String,
)
data class GPU(
/** model without brand name */
val model: String,
/** teraflops **/
val tFlops: Double,
/** vram in MB per gpu */
val memoryCapacity: Int,
/** vram bandwidth in GB/s (TODO find out) */
val memoryBandwidth: Double,
/** pcie gpu lanes like 8 */
val pcieLanes: Int,
/** pcie version like 3.0 or 4.0 */
val pcieGen: Double,
/** pcie bandwidth in GB/s (TODO find out) */
val pcieBandwidth: Double,
/** cuda version like 12.2 */
val cudaVersion: Double,
/** nvidia driver version like 545.23.06 */
val driverVersion: String,
/** not sure, changes with gpu series, like 860 for rtx 3000 series
* TODO should it even be here? */
val computeCap: Int
)
enum class HostingClass {
PRIVATE, DATACENTER
}
enum class MachineVerification {
VERIFIED, UNVERIFIED, VERIFICATION_REMOVED;

View file

@ -0,0 +1,28 @@
package eu.m724.vastapp.vastai.data
import org.json.JSONObject
data class MarketInstance(
/** id of the market instance, it changes after renting */
val listingId: Int,
val instance: Instance,
/** machine disk space in GB */
val diskSpace: Double,
/** if the instance is rented by you */
val owned: Boolean,
/** is the instance available for rental (rentable) */
val available: Boolean
) {
companion object {
fun fromJson(json: JSONObject): MarketInstance {
return MarketInstance(
json.getInt("id"),
Instance.fromJson(json),
json.getDouble("disk_space"),
json.getBoolean("owned"),
json.getBoolean("rentable")
)
}
}
}

View file

@ -1,5 +1,13 @@
package eu.m724.vastapp.vastai.data
import org.json.JSONObject
/*
price is probably the correct word but I'm not sure so I leave it as it is in the api
Cost is what it takes to make something, while Price is what you charge for it.
- llama
*/
data class Pricing(
/** if you're bidding this instance, always false in marketplace (or not?) */
val isBid: Boolean,
@ -9,12 +17,26 @@ data class Pricing(
/** dollars per hour excluding storage costs */
val dphBase: Double,
/** storage cost 1 GB / 30 days (720 hours)
* to get hourly, divide it by 720 and multiply by GBs TODO remove this comment */
/** storage cost GB/hr */
/** dollars per hour including storage costs */
val dphTotal: Double?,
/** storage cost $/GB*hr */
val storageCost: Double,
/** dollars per 1 GB of download (on site it shows TB as 1024 so TODO gb or gib?) **/
val downloadCost: Double,
/** dollars per 1 GB of upload (on site it shows TB as 1024) **/
val uploadCost: Double,
)
) {
companion object {
fun fromJson(json: JSONObject): Pricing {
return Pricing(
json.getBoolean("is_bid"),
json.getDouble("min_bid"),
json.getDouble("dph_base"),
json.getDouble("dph_total"),
json.getDouble("storage_cost") / 720,
json.getDouble("inet_down_cost"),
json.getDouble("inet_up_cost")
)
}
}
}

View file

@ -1,17 +1,17 @@
package eu.m724.vastapp.vastai.data
import android.net.InetAddresses
import java.net.InetAddress
import eu.m724.vastapp.vastai.StorageCapacityConverters
import org.json.JSONObject
data class RentedInstance(
/** the rental id */
val rentalId: Int,
val instance: Instance,
/** the rental id, apparently not rented id is different */
val rentalId: Int,
/** rented disk space in MB */
val diskSpace: Int,
/** disk usage in MB */
val diskUsage: Int,
/** rented disk space in GB (TODO GB?) */
val diskSpace: Double,
/** disk usage in GB (TODO GB?) */
val diskUsage: Double,
/** vram usage in MB */
val vramUsage: Int,
/** ram usage in MB */
@ -36,10 +36,33 @@ data class RentedInstance(
/** the docker image that runs on the instance */
val image: String,
/** label set by user */
val label: String,
/** label set by user, null if not set */
val label: String?,
/** local ip addresses?
* I think if you have another instance on the same machine you can use it */
val localIpAddresses: List<InetAddress>
)
val localIpAddresses: List<String>
) {
companion object {
fun fromJson(json: JSONObject): RentedInstance {
return RentedInstance(
json.getInt("id"),
Instance.fromJson(json),
json.getDouble("disk_space"),
json.getDouble("disk_util"),
(StorageCapacityConverters.gibToGb(json.getDouble("vmem_usage")) / 1000).toInt(),
(json.getDouble("mem_usage") / 1000).toInt(),
json.getDouble("gpu_util") / 100,
json.getDouble("cpu_util") / 100,
json.getDouble("gpu_temp"),
json.getDouble("inet_down_billed").toInt(),
json.getDouble("inet_up_billed").toInt(),
json.getString("ssh_host"),
json.getInt("ssh_port"),
json.getString("image_uuid"),
json.optString("label").takeIf { it.isNotBlank() },
json.getString("local_ipaddrs").split(" ").filterNot { it == "\n" }
)
}
}
}

View file

@ -19,7 +19,7 @@
"image_runtype": "str", // "ssh" if has ssh, "ssh_direc" if can connect directly, "ssh_proxy" if can connect via proxy. other types probably exist
"extra_env": "list", // docker arguments and environment variables, set in iamge config
"onstart": "str", // script that runs on start, set in iamge config
"label": "NoneType", // label set by user
"label": "str", // label set by user
"jupyter_token": "str",
"status_msg": "str", // status but longer
"gpu_util": "float", // 0 - 100