Skip to content

Commit 8f5ca78

Browse files
committed
Merge branch 'development' into development_2.7_handle_rentedNode
2 parents 17af673 + 4dd5f0f commit 8f5ca78

File tree

15 files changed

+295
-119
lines changed

15 files changed

+295
-119
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import { Features, FilterOptions, GatewayNameModel, GridClient, MachinesModel, NodeInfo } from "../../src";
2+
import { config, getClient } from "../client_loader";
3+
import { log, pingNodes } from "../utils";
4+
5+
async function deploy(client: GridClient, vms: MachinesModel, subdomain: string, gatewayNode: NodeInfo) {
6+
// Deploy VM
7+
const resultVM = await client.machines.deploy(vms);
8+
log("================= Deploying VM =================");
9+
log(resultVM);
10+
log("================= Deploying VM =================");
11+
12+
// Get WG interface details
13+
const wgnet = (await client.machines.getObj(vms.name))[0].interfaces[0];
14+
15+
// Deploy Gateway
16+
const gateway: GatewayNameModel = {
17+
name: subdomain,
18+
network: wgnet.network,
19+
node_id: gatewayNode.nodeId,
20+
tls_passthrough: false,
21+
backends: [`http://${wgnet.ip}:8080`],
22+
};
23+
24+
const resultGateway = await client.gateway.deploy_name(gateway);
25+
log("================= Deploying Gateway =================");
26+
log(resultGateway);
27+
log("================= Deploying Gateway =================");
28+
}
29+
30+
async function getDeployment(client: GridClient, name: string, subdomain: string) {
31+
// Get VM deployment
32+
const resultVM = await client.machines.getObj(name);
33+
log("================= Getting VM Deployment =================");
34+
log(resultVM);
35+
log("================= Getting VM Deployment =================");
36+
37+
// Get Gateway deployment
38+
const resultGateway = await client.gateway.getObj(subdomain);
39+
log("================= Getting Gateway Deployment =================");
40+
log(resultGateway);
41+
log(`https://${resultGateway[0].domain}`);
42+
log("================= Getting Gateway Deployment =================");
43+
}
44+
45+
async function cancel(client: GridClient, name: string, subdomain: string) {
46+
// Cancel VM deployment
47+
const resultVM = await client.machines.delete({ name });
48+
log("================= Canceling VM Deployment =================");
49+
log(resultVM);
50+
log("================= Canceling VM Deployment =================");
51+
52+
// Cancel Gateway deployment
53+
const resultGateway = await client.gateway.delete_name({ name: subdomain });
54+
log("================= Canceling Gateway Deployment =================");
55+
log(resultGateway);
56+
log("================= Canceling Gateway Deployment =================");
57+
}
58+
59+
async function main() {
60+
const name = "newnostr1";
61+
const grid3 = await getClient(`nostr/${name}`);
62+
const subdomain = `ntt${grid3.twinId}${name}`;
63+
const instanceCapacity = { cru: 2, mru: 4, sru: 50 };
64+
65+
// VM Query Options
66+
const vmQueryOptions: FilterOptions = {
67+
features: [Features.wireguard, Features.mycelium],
68+
cru: instanceCapacity.cru,
69+
mru: instanceCapacity.mru,
70+
sru: instanceCapacity.sru,
71+
availableFor: grid3.twinId,
72+
farmId: 1,
73+
};
74+
75+
// Gateway Query Options
76+
const gatewayQueryOptions: FilterOptions = {
77+
features: [Features.wireguard, Features.mycelium],
78+
gateway: true,
79+
availableFor: grid3.twinId,
80+
};
81+
82+
const gatewayNodes = await grid3.capacity.filterNodes(gatewayQueryOptions);
83+
const gatewayNodeId = await pingNodes(grid3, gatewayNodes);
84+
const gatewayNode = gatewayNodes.find(node => node.nodeId == gatewayNodeId);
85+
const nodes = await grid3.capacity.filterNodes(vmQueryOptions);
86+
const vmNode = await pingNodes(grid3, nodes);
87+
const domain = `${subdomain}.${gatewayNode!.publicConfig.domain}`;
88+
89+
const vms: MachinesModel = {
90+
name,
91+
network: {
92+
name: "nostrnet",
93+
ip_range: "10.252.0.0/16",
94+
addAccess: true,
95+
accessNodeId: gatewayNode!.nodeId,
96+
},
97+
machines: [
98+
{
99+
name: "nostr",
100+
node_id: vmNode,
101+
disks: [
102+
{
103+
name: "nsDisk",
104+
size: instanceCapacity.sru,
105+
mountpoint: "/mnt/data",
106+
},
107+
],
108+
planetary: true,
109+
public_ip: false,
110+
public_ip6: false,
111+
mycelium: true,
112+
cpu: instanceCapacity.cru,
113+
memory: 1024 * instanceCapacity.mru,
114+
rootfs_size: 0,
115+
flist: "https://hub.grid.tf/tf-official-apps/nostr_relay-mycelium.flist",
116+
entrypoint: "/sbin/zinit init",
117+
env: {
118+
SSH_KEY: config.ssh_key,
119+
NOSTR_HOSTNAME: domain,
120+
},
121+
},
122+
],
123+
metadata: "",
124+
description: "Deploying Nostr instance via TS Grid3 client",
125+
};
126+
127+
// Deploy VM and Gateway
128+
await deploy(grid3, vms, subdomain, gatewayNode!);
129+
130+
// Get the deployment details
131+
await getDeployment(grid3, name, subdomain);
132+
133+
// Uncomment the line below to cancel the deployment
134+
// await cancel(grid3, name, subdomain);
135+
136+
await grid3.disconnect();
137+
}
138+
139+
main();

packages/grid_client/src/clients/tf-grid/contracts.ts

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ export interface GetConsumptionOptions {
109109
graphqlURL: string;
110110
id: number;
111111
}
112+
export interface Consumption {
113+
amountBilled: number;
114+
discountReceived: DiscountLevel;
115+
}
112116

113117
export interface GetDiscountPackageOptions {
114118
graphqlURL: string;
@@ -268,7 +272,7 @@ class TFContracts extends Contracts {
268272
const gqlClient = new Graphql(options.graphqlURL);
269273

270274
const body = `query getConsumption($contractId: BigInt!){
271-
contractBillReports(where: {contractID_eq: $contractId} , orderBy: timestamp_DESC) {
275+
contractBillReports(where: {contractID_eq: $contractId} , orderBy: timestamp_DESC, limit:1) {
272276
discountReceived
273277
274278
}
@@ -282,7 +286,7 @@ class TFContracts extends Contracts {
282286
if (billReports.length === 0) {
283287
return "None";
284288
} else {
285-
const discountPackage = billReports[billReports.length - 1].discountReceived;
289+
const discountPackage = billReports[0].discountReceived;
286290
return discountPackage;
287291
}
288292
} catch (err) {
@@ -291,17 +295,19 @@ class TFContracts extends Contracts {
291295
}
292296
}
293297
/**
294-
* Get contract consumption per hour in TFT.
298+
* Get the contract consumption details per hour in TFT.
295299
*
296300
* @param {GetConsumptionOptions} options
297-
* @returns {Promise<number>}
301+
* @returns {Promise<Consumption>} A promise resolving to the consumption details,
302+
* including the amount billed and the discount received.
298303
*/
299-
async getConsumption(options: GetConsumptionOptions): Promise<number> {
304+
async getConsumption(options: GetConsumptionOptions): Promise<Consumption> {
300305
const gqlClient = new Graphql(options.graphqlURL);
301306
const body = `query getConsumption($contractId: BigInt!){
302307
contractBillReports(where: {contractID_eq: $contractId}, limit: 2 , orderBy: timestamp_DESC) {
303308
amountBilled
304309
timestamp
310+
discountReceived
305311
}
306312
nodeContracts(where: {contractID_eq: $contractId}) {
307313
createdAt
@@ -318,7 +324,10 @@ class TFContracts extends Contracts {
318324
const gqlConsumption: GqlConsumption = response["data"] as GqlConsumption;
319325
const billReports = gqlConsumption.contractBillReports;
320326
if (billReports.length === 0) {
321-
return 0;
327+
return {
328+
amountBilled: 0,
329+
discountReceived: "None",
330+
};
322331
} else {
323332
let duration = 1;
324333
const amountBilled = new Decimal(billReports[0].amountBilled);
@@ -338,10 +347,13 @@ class TFContracts extends Contracts {
338347
}
339348
}
340349
}
341-
return amountBilled
342-
.div(duration || 1)
343-
.div(10 ** 7)
344-
.toNumber();
350+
return {
351+
amountBilled: amountBilled
352+
.div(duration || 1)
353+
.div(10 ** 7)
354+
.toNumber(),
355+
discountReceived: billReports[0].discountReceived,
356+
};
345357
}
346358
} catch (err) {
347359
(err as Error).message = formatErrorMessage(`Error getting consumption for contract ${options.id}.`, err);

packages/grid_client/src/modules/contracts.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { GridClientError } from "@threefold/types";
1010
import * as PATH from "path";
1111

1212
import {
13+
Consumption,
1314
ContractsOverdue,
1415
type DiscountLevel,
1516
GqlContracts,
@@ -539,17 +540,18 @@ class Contracts {
539540
return this.client.contracts.getDiscountPackage({ id: options.id, graphqlURL: this.config.graphqlURL });
540541
}
541542
/**
542-
* Get contract consumption per hour in TFT.
543+
* Get the contract consumption details per hour in TFT.
543544
*
544-
* @param {ContractConsumption} options
545-
* @returns {Promise<number>}
545+
* @param {ContractConsumption} options - The contract consumption parameters.
546+
* @returns {Promise<Consumption>} A promise resolving to the consumption details,
547+
* including the amount billed and the discount received.
546548
* @decorators
547549
* - `@expose`: Exposes the method for external use.
548550
* - `@validateInput`: Validates the input options.
549551
*/
550552
@expose
551553
@validateInput
552-
async getConsumption(options: ContractConsumption): Promise<number> {
554+
async getConsumption(options: ContractConsumption): Promise<Consumption> {
553555
return this.client.contracts.getConsumption({ id: options.id, graphqlURL: this.config.graphqlURL });
554556
}
555557

packages/grid_client/src/modules/models.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,7 @@ class FilterOptions {
624624
@Expose() @IsOptional() @IsInt({ each: true }) @Min(1, { each: true }) nodeExclude?: number[];
625625
@Expose() @IsOptional() @IsInt({ each: true }) @Min(1, { each: true }) farmIds?: number[];
626626
@Expose() @IsOptional() @IsInt() @Min(1) farmId?: number;
627+
@Expose() @IsOptional() @IsInt() @Min(1) nodeId?: number;
627628
@Expose() @IsOptional() @IsString() farmName?: string;
628629
@Expose() @IsOptional() @IsString() country?: string;
629630
@Expose() @IsOptional() @IsString() city?: string;

packages/grid_client/src/primitives/nodes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ class Nodes {
466466
healthy: options.healthy,
467467
sort_by: SortBy.FreeCRU,
468468
sort_order: SortOrder.Desc,
469+
node_id: options.nodeId,
469470
rentable_or_rented_by: options.rentableOrRentedBy,
470471
features: options.features,
471472
};

0 commit comments

Comments
 (0)