CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/util/compute/cloud/hyperstack/compute-cost.ts
Views: 687
1
import type { HyperstackConfiguration } from "@cocalc/util/db-schema/compute-servers";
2
import type { HyperstackPriceData } from "./pricing";
3
import { optionKey, markup } from "./pricing";
4
5
// This is what we intend to use and charge for the boot disk.
6
export const BOOT_DISK_SIZE_GB = 50;
7
8
interface Options {
9
configuration: HyperstackConfiguration;
10
// output of getData from this package -- https://www.npmjs.com/package/@cocalc/gcloud-pricing-calculator
11
// except that package is backend only (it caches to disk), so data is obtained via an api, then used here.
12
priceData: HyperstackPriceData;
13
state?: "running" | "off" | "suspended";
14
}
15
16
export default function computeCost({
17
configuration,
18
priceData,
19
state = "running",
20
}: Options): number {
21
if (priceData == null) {
22
throw Error("priceData must not be null");
23
}
24
if (state == "off") {
25
return computeOffCost({ configuration, priceData });
26
} else if (state == "suspended") {
27
throw Error("Hyperstack does not support suspended");
28
} else if (state == "running") {
29
return computeRunningCost({ configuration, priceData });
30
} else {
31
throw Error(`computing cost for state "${state}" not implemented`);
32
}
33
}
34
35
function throwCostNotKnownError(configuration) {
36
const { flavor_name, region_name } = configuration ?? {};
37
throw Error(
38
`no price known for flavor_name=${flavor_name}, region_name=${region_name}`,
39
);
40
}
41
42
export function computeDiskCost({ configuration, priceData }): number {
43
if (priceData == null) {
44
throwCostNotKnownError(configuration);
45
}
46
return (configuration?.diskSizeGb ?? 10) * priceData.ssd_cost_per_hour;
47
}
48
49
// export function computeBootVolumeCost({ configuration, priceData }): number {
50
// if (priceData == null) {
51
// throwCostNotKnownError(configuration);
52
// }
53
// return BOOT_DISK_SIZE_GB * priceData.ssd_cost_per_hour;
54
// }
55
56
export function computeVolumeCost(opts) {
57
return computeDiskCost(opts);
58
}
59
60
// For the cocalc integration "off" means that we 100% delete the VM
61
// and *ONLY* keep the associated storage volumes.
62
function computeOffCost({ configuration, priceData }) {
63
return markup({
64
cost: computeVolumeCost({ configuration, priceData }),
65
priceData,
66
});
67
}
68
69
function computeRunningCost({ configuration, priceData }) {
70
const data = priceData?.options[optionKey(configuration)];
71
if (data == null) {
72
throwCostNotKnownError(configuration);
73
}
74
// data.cost_per_hour *includes* GPUs, any ephemeral storage and external ip (assume: not cpu only!)
75
const cost =
76
data.cost_per_hour + computeVolumeCost({ configuration, priceData });
77
return markup({ cost, priceData });
78
}
79
80