diff --git a/packages/grid_client/scripts/applications/casberlabs.ts b/packages/grid_client/scripts/applications/casberlabs.ts new file mode 100644 index 0000000000..17cab6e1a0 --- /dev/null +++ b/packages/grid_client/scripts/applications/casberlabs.ts @@ -0,0 +1,117 @@ +import { FilterOptions, GatewayNameModel, MachinesModel } from "../../src"; +import { config, getClient } from "../client_loader"; +import { log, pingNodes } from "../utils"; + +async function deploy(client, vms, subdomain, gatewayNode) { + const resultVM = await client.machines.deploy(vms); + log("================= Deploying VM ================="); + log(resultVM); + log("================= Deploying VM ================="); + + const vmPlanetary = (await client.machines.getObj(vms.name))[0].planetary; + //Name Gateway Model + const gw: GatewayNameModel = { + name: subdomain, + node_id: gatewayNode.nodeId, + tls_passthrough: false, + backends: ["http://[" + vmPlanetary + "]:80"], + }; + + const resultGateway = await client.gateway.deploy_name(gw); + log("================= Deploying name gateway ================="); + log(resultGateway); + log("================= Deploying name gateway ================="); +} + +async function getDeployment(client, vms, gw) { + const resultVM = await client.machines.getObj(vms.name); + const resultGateway = await client.gateway.getObj(gw); + log("================= Getting deployment information ================="); + log(resultVM); + log(resultGateway); + log("https://" + resultGateway[0].domain); + log("================= Getting deployment information ================="); +} + +async function cancel(client, vms, gw) { + const resultVM = await client.machines.delete(vms); + const resultGateway = await client.gateway.delete_name(gw); + log("================= Canceling the deployment ================="); + log(resultVM); + log(resultGateway); + log("================= Canceling the deployment ================="); +} + +async function main() { + const name = "newcasperlabs"; + const grid3 = await getClient(`casperlabs/${name}`); + const subdomain = "cl" + grid3.twinId + name; + const instanceCapacity = { cru: 2, mru: 4, sru: 100 }; // Update the instance capacity values according to your requirements. + + //VMNode Selection + const vmQueryOptions: FilterOptions = { + cru: instanceCapacity.cru, + mru: instanceCapacity.mru, + sru: instanceCapacity.sru, + availableFor: grid3.twinId, + farmId: 1, + }; + //GatewayNode Selection + const gatewayQueryOptions: FilterOptions = { + gateway: true, + availableFor: grid3.twinId, + }; + const gatewayNode = (await grid3.capacity.filterNodes(gatewayQueryOptions))[0]; + const nodes = await grid3.capacity.filterNodes(vmQueryOptions); + const vmNode = await pingNodes(grid3, nodes); + const domain = subdomain + "." + gatewayNode.publicConfig.domain; + + const vms: MachinesModel = { + name, + network: { + name: "wedtest", + ip_range: "10.249.0.0/16", + }, + machines: [ + { + name: "casperlabs", + node_id: vmNode, + disks: [ + { + name: "wedDisk", + size: instanceCapacity.sru, + mountpoint: "/data", + }, + ], + planetary: true, + public_ip: false, + public_ip6: false, + mycelium: false, + cpu: instanceCapacity.cru, + memory: 1024 * instanceCapacity.mru, + rootfs_size: 0, + flist: "https://hub.grid.tf/tf-official-apps/casperlabs-latest.flist", + entrypoint: "/sbin/zinit init", + env: { + SSH_KEY: config.ssh_key, + CASPERLABS_HOSTNAME: domain, + }, + }, + ], + metadata: "", + description: "test deploying CasberLabs via ts grid3 client", + }; + + //Deploy VMs + await deploy(grid3, vms, subdomain, gatewayNode); + + //Get the deployment + await getDeployment(grid3, vms, subdomain); + + //Uncomment the line below to cancel the deployment + // await cancel(grid3, { name }, { name: subdomain }); + + await grid3.disconnect(); +} + +main(); diff --git a/packages/grid_client/scripts/applications/funkwhale.ts b/packages/grid_client/scripts/applications/funkwhale.ts new file mode 100644 index 0000000000..ed2adf3691 --- /dev/null +++ b/packages/grid_client/scripts/applications/funkwhale.ts @@ -0,0 +1,121 @@ +import { FilterOptions, GatewayNameModel, MachinesModel } from "../../src"; +import { config, getClient } from "../client_loader"; +import { log, pingNodes } from "../utils"; + +async function deploy(client, vms, subdomain, gatewayNode) { + const resultVM = await client.machines.deploy(vms); + log("================= Deploying VM ================="); + log(resultVM); + log("================= Deploying VM ================="); + + const vmPlanetary = (await client.machines.getObj(vms.name))[0].planetary; + //Name Gateway Model + const gw: GatewayNameModel = { + name: subdomain, + node_id: gatewayNode.nodeId, + tls_passthrough: false, + backends: ["http://[" + vmPlanetary + "]:80"], + }; + + const resultGateway = await client.gateway.deploy_name(gw); + log("================= Deploying name gateway ================="); + log(resultGateway); + log("================= Deploying name gateway ================="); +} + +async function getDeployment(client, vms, gw) { + const resultVM = await client.machines.getObj(vms.name); + const resultGateway = await client.gateway.getObj(gw); + log("================= Getting deployment information ================="); + log(resultVM); + log(resultGateway); + log("https://" + resultGateway[0].domain); + log("================= Getting deployment information ================="); +} + +async function cancel(client, vms, gw) { + const resultVM = await client.machines.delete(vms); + const resultGateway = await client.gateway.delete_name(gw); + log("================= Canceling the deployment ================="); + log(resultVM); + log(resultGateway); + log("================= Canceling the deployment ================="); +} + +async function main() { + const name = "newfunkwhale"; + const grid3 = await getClient(`funkwhale/${name}`); + const subdomain = "fw" + grid3.twinId + name; + const instanceCapacity = { cru: 1, mru: 2, sru: 50 }; // Update the instance capacity values according to your requirements. + + //VMNode Selection + const vmQueryOptions: FilterOptions = { + cru: instanceCapacity.cru, + mru: instanceCapacity.mru, + sru: instanceCapacity.sru, + availableFor: grid3.twinId, + farmId: 1, + }; + //GatewayNode Selection + const gatewayQueryOptions: FilterOptions = { + gateway: true, + availableFor: grid3.twinId, + }; + const gatewayNode = (await grid3.capacity.filterNodes(gatewayQueryOptions))[0]; + const nodes = await grid3.capacity.filterNodes(vmQueryOptions); + const vmNode = await pingNodes(grid3, nodes); + const domain = subdomain + "." + gatewayNode.publicConfig.domain; + + const vms: MachinesModel = { + name, + network: { + name: "wedtest", + ip_range: "10.249.0.0/16", + }, + machines: [ + { + name: "funkwhale", + node_id: vmNode, + disks: [ + { + name: "wedDisk", + size: instanceCapacity.sru, + mountpoint: "/data", + }, + ], + planetary: true, + public_ip: false, + public_ip6: false, + mycelium: false, + cpu: instanceCapacity.cru, + memory: 1024 * instanceCapacity.mru, + rootfs_size: 0, + flist: "https://hub.grid.tf/tf-official-apps/funkwhale-dec21.flist", + entrypoint: "/init.sh", + env: { + SSH_KEY: config.ssh_key, + FUNKWHALE_HOSTNAME: domain, + // These email, username, and password will be used to log in to your instance, so please update them with your own. + DJANGO_SUPERUSER_EMAIL: "admin123@funk.whale", + DJANGO_SUPERUSER_USERNAME: "admin123", + DJANGO_SUPERUSER_PASSWORD: "admin123", + }, + }, + ], + metadata: "", + description: "test deploying FunkWhale via ts grid3 client", + }; + + //Deploy VMs + await deploy(grid3, vms, subdomain, gatewayNode); + + //Get the deployment + await getDeployment(grid3, vms, subdomain); + + //Uncomment the line below to cancel the deployment + // await cancel(grid3, { name }, { name: subdomain }); + + await grid3.disconnect(); +} + +main(); diff --git a/packages/grid_client/scripts/applications/mattermost.ts b/packages/grid_client/scripts/applications/mattermost.ts new file mode 100644 index 0000000000..42a16569fe --- /dev/null +++ b/packages/grid_client/scripts/applications/mattermost.ts @@ -0,0 +1,127 @@ +import { FilterOptions, GatewayNameModel, MachinesModel } from "../../src"; +import { config, getClient } from "../client_loader"; +import { log, pingNodes } from "../utils"; + +async function deploy(client, vms, subdomain, gatewayNode) { + const resultVM = await client.machines.deploy(vms); + log("================= Deploying VM ================="); + log(resultVM); + log("================= Deploying VM ================="); + + const vmPlanetary = (await client.machines.getObj(vms.name))[0].planetary; + //Name Gateway Model + const gw: GatewayNameModel = { + name: subdomain, + node_id: gatewayNode.nodeId, + tls_passthrough: false, + backends: ["http://[" + vmPlanetary + "]:8000"], + }; + + const resultGateway = await client.gateway.deploy_name(gw); + log("================= Deploying name gateway ================="); + log(resultGateway); + log("================= Deploying name gateway ================="); +} + +async function getDeployment(client, vms, gw) { + const resultVM = await client.machines.getObj(vms.name); + const resultGateway = await client.gateway.getObj(gw); + log("================= Getting deployment information ================="); + log(resultVM); + log(resultGateway); + log("https://" + resultGateway[0].domain); + log("================= Getting deployment information ================="); +} + +async function cancel(client, vms, gw) { + const resultVM = await client.machines.delete(vms); + const resultGateway = await client.gateway.delete_name(gw); + log("================= Canceling the deployment ================="); + log(resultVM); + log(resultGateway); + log("================= Canceling the deployment ================="); +} + +async function main() { + const name = "newmattermost"; + const grid3 = await getClient(`mattermost/${name}`); + const subdomain = "mm" + grid3.twinId + name; + const instanceCapacity = { cru: 1, mru: 2, sru: 15 }; // Update the instance capacity values according to your requirements. + + //VMNode Selection + const vmQueryOptions: FilterOptions = { + cru: instanceCapacity.cru, + mru: instanceCapacity.mru, + sru: instanceCapacity.sru, + availableFor: grid3.twinId, + farmId: 1, + }; + //GatewayNode Selection + const gatewayQueryOptions: FilterOptions = { + gateway: true, + availableFor: grid3.twinId, + }; + const gatewayNode = (await grid3.capacity.filterNodes(gatewayQueryOptions))[0]; + const nodes = await grid3.capacity.filterNodes(vmQueryOptions); + const vmNode = await pingNodes(grid3, nodes); + const domain = subdomain + "." + gatewayNode.publicConfig.domain; + + const vms: MachinesModel = { + name, + network: { + name: "wedtest", + ip_range: "10.249.0.0/16", + }, + machines: [ + { + name: "mattermost", + node_id: vmNode, + disks: [ + { + name: "wedDisk", + size: instanceCapacity.sru, + mountpoint: "/var/lib/docker", + }, + ], + planetary: true, + public_ip: false, + public_ip6: false, + mycelium: false, + cpu: instanceCapacity.cru, + memory: 1024 * instanceCapacity.mru, + rootfs_size: 0, + flist: "https://hub.grid.tf/tf-official-apps/mattermost-latest.flist", + entrypoint: "/sbin/zinit init", + env: { + SSH_KEY: config.ssh_key, + MATTERMOST_DOMAIN: domain, + SITE_URL: "https://" + domain, + // These email and password will be used as admin credentials, so please update them with your own. + DJANGO_SUPERUSER_EMAIL: "admin123@matter.most", + DB_PASSWORD: "admin123", + /* The SMTP server is optional, if you would like to enable the access of the SMTP server, you need to send these values. + These credentials will be used as admin credentials, so please configure them with your own. */ + // SMTPUsername: "username", + // SMTPPassword: "password", + // SMTPServer: "hostname", + // SMTPPort: "port", + }, + }, + ], + metadata: "", + description: "test deploying MatterMost via ts grid3 client", + }; + + //Deploy VMs + await deploy(grid3, vms, subdomain, gatewayNode); + + //Get the deployment + await getDeployment(grid3, vms, subdomain); + + //Uncomment the line below to cancel the deployment + // await cancel(grid3, { name }, { name: subdomain }); + + await grid3.disconnect(); +} + +main(); diff --git a/packages/grid_client/scripts/applications/peertube.ts b/packages/grid_client/scripts/applications/peertube.ts new file mode 100644 index 0000000000..60d94c82d4 --- /dev/null +++ b/packages/grid_client/scripts/applications/peertube.ts @@ -0,0 +1,120 @@ +import { FilterOptions, GatewayNameModel, MachinesModel } from "../../src"; +import { config, getClient } from "../client_loader"; +import { log, pingNodes } from "../utils"; + +async function deploy(client, vms, subdomain, gatewayNode) { + const resultVM = await client.machines.deploy(vms); + log("================= Deploying VM ================="); + log(resultVM); + log("================= Deploying VM ================="); + + const vmPlanetary = (await client.machines.getObj(vms.name))[0].planetary; + //Name Gateway Model + const gw: GatewayNameModel = { + name: subdomain, + node_id: gatewayNode.nodeId, + tls_passthrough: false, + backends: ["http://[" + vmPlanetary + "]:9000"], + }; + + const resultGateway = await client.gateway.deploy_name(gw); + log("================= Deploying name gateway ================="); + log(resultGateway); + log("================= Deploying name gateway ================="); +} + +async function getDeployment(client, vms, gw) { + const resultVM = await client.machines.getObj(vms.name); + const resultGateway = await client.gateway.getObj(gw); + log("================= Getting deployment information ================="); + log(resultVM); + log(resultGateway); + log("https://" + resultGateway[0].domain); + log("================= Getting deployment information ================="); +} + +async function cancel(client, vms, gw) { + const resultVM = await client.machines.delete(vms); + const resultGateway = await client.gateway.delete_name(gw); + log("================= Canceling the deployment ================="); + log(resultVM); + log(resultGateway); + log("================= Canceling the deployment ================="); +} + +async function main() { + const name = "newpeertube"; + const grid3 = await getClient(`peertube/${name}`); + const subdomain = "pt" + grid3.twinId + name; + const instanceCapacity = { cru: 1, mru: 2, sru: 15 }; // Update the instance capacity values according to your requirements. + + //VMNode Selection + const vmQueryOptions: FilterOptions = { + cru: instanceCapacity.cru, + mru: instanceCapacity.mru, + sru: instanceCapacity.sru, + availableFor: grid3.twinId, + farmId: 1, + }; + //GatewayNode Selection + const gatewayQueryOptions: FilterOptions = { + gateway: true, + availableFor: grid3.twinId, + }; + const gatewayNode = (await grid3.capacity.filterNodes(gatewayQueryOptions))[0]; + const nodes = await grid3.capacity.filterNodes(vmQueryOptions); + const vmNode = await pingNodes(grid3, nodes); + const domain = subdomain + "." + gatewayNode.publicConfig.domain; + + const vms: MachinesModel = { + name, + network: { + name: "wedtest", + ip_range: "10.249.0.0/16", + }, + machines: [ + { + name: "peertube", + node_id: vmNode, + disks: [ + { + name: "wedDisk", + size: instanceCapacity.sru, + mountpoint: "/data", + }, + ], + planetary: true, + public_ip: false, + public_ip6: false, + mycelium: false, + cpu: instanceCapacity.cru, + memory: 1024 * instanceCapacity.mru, + rootfs_size: 0, + flist: "https://hub.grid.tf/tf-official-apps/peertube-v3.1.1.flist", + entrypoint: "/sbin/zinit init", + env: { + SSH_KEY: config.ssh_key, + PEERTUBE_WEBSERVER_HOSTNAME: domain, + // These email, and password will be used to log in to your instance, so please update them with your own. + PEERTUBE_ADMIN_EMAIL: "admin123@peer.tube", + PT_INITIAL_ROOT_PASSWORD: "admin123", + }, + }, + ], + metadata: "", + description: "test deploying PeerTube via ts grid3 client", + }; + + //Deploy VMs + await deploy(grid3, vms, subdomain, gatewayNode); + + //Get the deployment + await getDeployment(grid3, vms, subdomain); + + //Uncomment the line below to cancel the deployment + // await cancel(grid3, { name }, { name: subdomain }); + + await grid3.disconnect(); +} + +main(); diff --git a/packages/grid_client/scripts/utils.ts b/packages/grid_client/scripts/utils.ts index 859c78998c..35525d7358 100644 --- a/packages/grid_client/scripts/utils.ts +++ b/packages/grid_client/scripts/utils.ts @@ -1,6 +1,32 @@ import { inspect } from "util"; +import { GridClient, NodeInfo } from "../src"; + function log(message) { console.log(inspect(message, { showHidden: false, depth: null, colors: true })); } -export { log }; + +/** + * Attempts to ping a list of nodes sequentially and returns the ID of the first responsive node. + * + * This function iterates through an array of nodes, pinging each one to check its responsiveness. + * It returns the ID of the first node that responds successfully. If no nodes respond, an error is thrown. + * + * @param {GridClient} client - An instance of the GridClient used to ping the nodes. + * @param {NodeInfo[]} nodes - An array of node information objects. + * @returns {Promise} - A promise that resolves to the nodeId of the first responsive node. + * @throws {Error} - Throws an error if none of the nodes respond successfully. + */ +async function pingNodes(client: GridClient, nodes: NodeInfo[]): Promise { + for (const node of nodes) { + try { + await client.zos.pingNode({ nodeId: node.nodeId }); + return node.nodeId; + } catch (error) { + log("node " + node.nodeId + " is not responding, trying different node."); + } + } + throw new Error("There are no available nodes. Please try changing the filters you have applied."); +} + +export { log, pingNodes };